gantt-lib 0.61.0 → 0.63.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/scheduling/index.d.mts +1 -1
- package/dist/core/scheduling/index.d.ts +1 -1
- package/dist/core/scheduling/index.js +0 -62
- package/dist/core/scheduling/index.js.map +1 -1
- package/dist/core/scheduling/index.mjs +0 -60
- package/dist/core/scheduling/index.mjs.map +1 -1
- package/dist/{index-BlUshzVg.d.mts → index-DMA7NbWe.d.mts} +1 -35
- package/dist/{index-BlUshzVg.d.ts → index-DMA7NbWe.d.ts} +1 -35
- package/dist/index.d.mts +37 -3
- package/dist/index.d.ts +37 -3
- package/dist/index.js +228 -121
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +228 -121
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
export { D as DAY_MS, a as DependencyError, L as LinkType,
|
|
1
|
+
export { D as DAY_MS, a as DependencyError, L as LinkType, U as ScheduleCommandOptions, X as ScheduleCommandResult, Y as ScheduleDependency, Z as ScheduleTask, _ as ScheduleTaskUpdate, T as Task, $ as TaskDependency, V as ValidationResult, a0 as addBusinessDays, e as alignToWorkingDay, f as areTasksHierarchicallyRelated, g as buildAdjacencyList, h as buildTaskRangeFromEnd, i as buildTaskRangeFromStart, j as calculateSuccessorDate, k as cascadeByLinks, l as clampTaskRangeForIncomingFS, m as computeLagFromDates, n as computeParentDates, o as computeParentProgress, p as detectCycles, q as findParentId, r as getAllDependencyEdges, s as getAllDescendants, t as getBusinessDayOffset, a1 as getBusinessDaysCount, u as getChildren, v as getDependencyLag, w as getSuccessorChain, x as getTaskDuration, y as getTransitiveCascadeChain, z as isAncestorTask, A as isTaskParent, B as moveTaskRange, C as moveTaskWithCascade, E as normalizeDependencyLag, F as normalizeUTCDate, H as parseDateOnly, I as recalculateIncomingLags, J as recalculateProjectSchedule, K as recalculateTaskFromDependencies, N as reflowTasksOnModeSwitch, O as removeDependenciesBetweenTasks, P as resizeTaskWithCascade, Q as shiftBusinessDayOffset, a2 as subtractBusinessDays, R as universalCascade, S as validateDependencies } from '../../index-DMA7NbWe.mjs';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { D as DAY_MS, a as DependencyError, L as LinkType,
|
|
1
|
+
export { D as DAY_MS, a as DependencyError, L as LinkType, U as ScheduleCommandOptions, X as ScheduleCommandResult, Y as ScheduleDependency, Z as ScheduleTask, _ as ScheduleTaskUpdate, T as Task, $ as TaskDependency, V as ValidationResult, a0 as addBusinessDays, e as alignToWorkingDay, f as areTasksHierarchicallyRelated, g as buildAdjacencyList, h as buildTaskRangeFromEnd, i as buildTaskRangeFromStart, j as calculateSuccessorDate, k as cascadeByLinks, l as clampTaskRangeForIncomingFS, m as computeLagFromDates, n as computeParentDates, o as computeParentProgress, p as detectCycles, q as findParentId, r as getAllDependencyEdges, s as getAllDescendants, t as getBusinessDayOffset, a1 as getBusinessDaysCount, u as getChildren, v as getDependencyLag, w as getSuccessorChain, x as getTaskDuration, y as getTransitiveCascadeChain, z as isAncestorTask, A as isTaskParent, B as moveTaskRange, C as moveTaskWithCascade, E as normalizeDependencyLag, F as normalizeUTCDate, H as parseDateOnly, I as recalculateIncomingLags, J as recalculateProjectSchedule, K as recalculateTaskFromDependencies, N as reflowTasksOnModeSwitch, O as removeDependenciesBetweenTasks, P as resizeTaskWithCascade, Q as shiftBusinessDayOffset, a2 as subtractBusinessDays, R as universalCascade, S as validateDependencies } from '../../index-DMA7NbWe.js';
|
|
@@ -29,7 +29,6 @@ __export(scheduling_exports, {
|
|
|
29
29
|
buildTaskRangeFromStart: () => buildTaskRangeFromStart,
|
|
30
30
|
calculateSuccessorDate: () => calculateSuccessorDate,
|
|
31
31
|
cascadeByLinks: () => cascadeByLinks,
|
|
32
|
-
clampDateRangeForIncomingFS: () => clampDateRangeForIncomingFS,
|
|
33
32
|
clampTaskRangeForIncomingFS: () => clampTaskRangeForIncomingFS,
|
|
34
33
|
computeLagFromDates: () => computeLagFromDates,
|
|
35
34
|
computeParentDates: () => computeParentDates,
|
|
@@ -58,7 +57,6 @@ __export(scheduling_exports, {
|
|
|
58
57
|
reflowTasksOnModeSwitch: () => reflowTasksOnModeSwitch,
|
|
59
58
|
removeDependenciesBetweenTasks: () => removeDependenciesBetweenTasks,
|
|
60
59
|
resizeTaskWithCascade: () => resizeTaskWithCascade,
|
|
61
|
-
resolveDateRangeFromPixels: () => resolveDateRangeFromPixels,
|
|
62
60
|
shiftBusinessDayOffset: () => shiftBusinessDayOffset,
|
|
63
61
|
subtractBusinessDays: () => subtractBusinessDays,
|
|
64
62
|
universalCascade: () => universalCascade,
|
|
@@ -1209,64 +1207,6 @@ function validateDependencies(tasks) {
|
|
|
1209
1207
|
errors
|
|
1210
1208
|
};
|
|
1211
1209
|
}
|
|
1212
|
-
|
|
1213
|
-
// src/adapters/scheduling/drag.ts
|
|
1214
|
-
function resolveDateRangeFromPixels(mode, left, width, monthStart, dayWidth, task, businessDays, weekendPredicate) {
|
|
1215
|
-
const dayOffset = Math.round(left / dayWidth);
|
|
1216
|
-
const rawStartDate = new Date(Date.UTC(
|
|
1217
|
-
monthStart.getUTCFullYear(),
|
|
1218
|
-
monthStart.getUTCMonth(),
|
|
1219
|
-
monthStart.getUTCDate() + dayOffset
|
|
1220
|
-
));
|
|
1221
|
-
const rawEndOffset = dayOffset + Math.round(width / dayWidth) - 1;
|
|
1222
|
-
const rawEndDate = new Date(Date.UTC(
|
|
1223
|
-
monthStart.getUTCFullYear(),
|
|
1224
|
-
monthStart.getUTCMonth(),
|
|
1225
|
-
monthStart.getUTCDate() + rawEndOffset
|
|
1226
|
-
));
|
|
1227
|
-
if (!(businessDays && weekendPredicate)) {
|
|
1228
|
-
return { start: rawStartDate, end: rawEndDate };
|
|
1229
|
-
}
|
|
1230
|
-
if (mode === "move") {
|
|
1231
|
-
const originalStart2 = new Date(task.startDate);
|
|
1232
|
-
const snapDirection2 = rawStartDate.getTime() >= originalStart2.getTime() ? 1 : -1;
|
|
1233
|
-
return moveTaskRange(
|
|
1234
|
-
task.startDate,
|
|
1235
|
-
task.endDate,
|
|
1236
|
-
rawStartDate,
|
|
1237
|
-
true,
|
|
1238
|
-
weekendPredicate,
|
|
1239
|
-
snapDirection2
|
|
1240
|
-
);
|
|
1241
|
-
}
|
|
1242
|
-
if (mode === "resize-right") {
|
|
1243
|
-
const fixedStart = new Date(task.startDate);
|
|
1244
|
-
const originalEnd = new Date(task.endDate);
|
|
1245
|
-
const snapDirection2 = rawEndDate.getTime() >= originalEnd.getTime() ? 1 : -1;
|
|
1246
|
-
const alignedEnd = alignToWorkingDay(rawEndDate, snapDirection2, weekendPredicate);
|
|
1247
|
-
const duration2 = Math.max(1, getBusinessDaysCount(fixedStart, alignedEnd, weekendPredicate));
|
|
1248
|
-
return buildTaskRangeFromStart(fixedStart, duration2, true, weekendPredicate);
|
|
1249
|
-
}
|
|
1250
|
-
const fixedEnd = new Date(task.endDate);
|
|
1251
|
-
const originalStart = new Date(task.startDate);
|
|
1252
|
-
const snapDirection = rawStartDate.getTime() >= originalStart.getTime() ? 1 : -1;
|
|
1253
|
-
const alignedStart = alignToWorkingDay(rawStartDate, snapDirection, weekendPredicate);
|
|
1254
|
-
const duration = Math.max(1, getBusinessDaysCount(alignedStart, fixedEnd, weekendPredicate));
|
|
1255
|
-
return buildTaskRangeFromEnd(fixedEnd, duration, true, weekendPredicate);
|
|
1256
|
-
}
|
|
1257
|
-
function clampDateRangeForIncomingFS(task, range, allTasks, mode, businessDays, weekendPredicate) {
|
|
1258
|
-
if (mode === "resize-right") {
|
|
1259
|
-
return range;
|
|
1260
|
-
}
|
|
1261
|
-
return clampTaskRangeForIncomingFS(
|
|
1262
|
-
task,
|
|
1263
|
-
range.start,
|
|
1264
|
-
range.end,
|
|
1265
|
-
allTasks,
|
|
1266
|
-
businessDays,
|
|
1267
|
-
weekendPredicate
|
|
1268
|
-
);
|
|
1269
|
-
}
|
|
1270
1210
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1271
1211
|
0 && (module.exports = {
|
|
1272
1212
|
DAY_MS,
|
|
@@ -1278,7 +1218,6 @@ function clampDateRangeForIncomingFS(task, range, allTasks, mode, businessDays,
|
|
|
1278
1218
|
buildTaskRangeFromStart,
|
|
1279
1219
|
calculateSuccessorDate,
|
|
1280
1220
|
cascadeByLinks,
|
|
1281
|
-
clampDateRangeForIncomingFS,
|
|
1282
1221
|
clampTaskRangeForIncomingFS,
|
|
1283
1222
|
computeLagFromDates,
|
|
1284
1223
|
computeParentDates,
|
|
@@ -1307,7 +1246,6 @@ function clampDateRangeForIncomingFS(task, range, allTasks, mode, businessDays,
|
|
|
1307
1246
|
reflowTasksOnModeSwitch,
|
|
1308
1247
|
removeDependenciesBetweenTasks,
|
|
1309
1248
|
resizeTaskWithCascade,
|
|
1310
|
-
resolveDateRangeFromPixels,
|
|
1311
1249
|
shiftBusinessDayOffset,
|
|
1312
1250
|
subtractBusinessDays,
|
|
1313
1251
|
universalCascade,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/scheduling/index.ts","../../../src/core/scheduling/dateMath.ts","../../../src/core/scheduling/dependencies.ts","../../../src/core/scheduling/hierarchy.ts","../../../src/core/scheduling/commands.ts","../../../src/core/scheduling/cascade.ts","../../../src/core/scheduling/execute.ts","../../../src/core/scheduling/validation.ts","../../../src/adapters/scheduling/drag.ts"],"sourcesContent":["/**\n * Core scheduling module — runtime-agnostic scheduling logic.\n * Zero React/DOM/date-fns dependencies.\n */\nexport * from './types';\nexport * from './dateMath';\nexport * from './dependencies';\nexport * from './cascade';\nexport * from './commands';\nexport * from './execute';\nexport * from './validation';\nexport * from './hierarchy';\n\n// UI adapter functions — re-exported for backward compatibility.\n// Consumers should migrate to importing from '../adapters/scheduling' instead.\n/** @deprecated Import from '../adapters/scheduling' instead */\nexport { resolveDateRangeFromPixels, clampDateRangeForIncomingFS } from '../../adapters/scheduling';\n","/**\n * Pure date math utilities for the core scheduling module.\n * Zero React/DOM/date-fns dependencies.\n *\n * Functions moved from:\n * - dependencyUtils.ts: normalizeUTCDate, parseDateOnly, getBusinessDayOffset, shiftBusinessDayOffset, DAY_MS\n * - dateUtils.ts: getBusinessDaysCount, addBusinessDays, subtractBusinessDays\n */\n\nexport const DAY_MS = 24 * 60 * 60 * 1000;\n\n/**\n * Normalize a Date to UTC midnight (hours/minutes/seconds zeroed).\n */\nexport function normalizeUTCDate(date: Date): Date {\n return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()));\n}\n\n/**\n * Parse a date string or Date object to a UTC midnight Date.\n * Handles ISO strings like \"2025-01-15\" by appending T00:00:00.000Z.\n */\nexport function parseDateOnly(date: string | Date): Date {\n const parsed = typeof date === 'string'\n ? new Date(`${date.split('T')[0]}T00:00:00.000Z`)\n : normalizeUTCDate(date);\n return normalizeUTCDate(parsed);\n}\n\n/**\n * Compute the business-day offset between two dates.\n * Steps through each calendar day, counting only non-weekend days.\n * Returns a positive number if toDate > fromDate, negative if toDate < fromDate.\n */\nexport function getBusinessDayOffset(\n fromDate: Date,\n toDate: Date,\n weekendPredicate: (date: Date) => boolean\n): number {\n const from = normalizeUTCDate(fromDate);\n const to = normalizeUTCDate(toDate);\n\n if (from.getTime() === to.getTime()) {\n return 0;\n }\n\n const step = to.getTime() > from.getTime() ? 1 : -1;\n const current = new Date(from);\n let offset = 0;\n\n while (current.getTime() !== to.getTime()) {\n current.setUTCDate(current.getUTCDate() + step);\n if (!weekendPredicate(current)) {\n offset += step;\n }\n }\n\n return offset;\n}\n\n/**\n * Shift a date by a business-day offset, skipping weekends.\n */\nexport function shiftBusinessDayOffset(\n date: Date,\n offset: number,\n weekendPredicate: (date: Date) => boolean\n): Date {\n const current = normalizeUTCDate(date);\n\n if (offset === 0) {\n return current;\n }\n\n const step = offset > 0 ? 1 : -1;\n let remaining = Math.abs(offset);\n\n while (remaining > 0) {\n current.setUTCDate(current.getUTCDate() + step);\n if (!weekendPredicate(current)) {\n remaining--;\n }\n }\n\n return current;\n}\n\n/**\n * Count business days between two dates (inclusive), excluding weekends.\n * Returns minimum 1.\n */\nexport function getBusinessDaysCount(\n startDate: string | Date,\n endDate: string | Date,\n weekendPredicate: (date: Date) => boolean\n): number {\n const start = typeof startDate === 'string'\n ? new Date(`${startDate.split('T')[0]}T00:00:00.000Z`)\n : normalizeUTCDate(startDate);\n const end = typeof endDate === 'string'\n ? new Date(`${endDate.split('T')[0]}T00:00:00.000Z`)\n : normalizeUTCDate(endDate);\n\n let count = 0;\n const current = new Date(start);\n\n while (current.getTime() <= end.getTime()) {\n if (!weekendPredicate(current)) {\n count++;\n }\n current.setUTCDate(current.getUTCDate() + 1);\n }\n\n return Math.max(1, count);\n}\n\n/**\n * Calculate end date by adding N business days to start date.\n * Returns a Date object.\n */\nexport function addBusinessDays(\n startDate: string | Date,\n businessDays: number,\n weekendPredicate: (date: Date) => boolean\n): Date {\n const start = typeof startDate === 'string'\n ? new Date(`${startDate.split('T')[0]}T00:00:00.000Z`)\n : normalizeUTCDate(startDate);\n const current = new Date(start);\n let targetDays = Math.max(1, businessDays);\n let businessDaysCounted = 0;\n\n while (businessDaysCounted < targetDays) {\n if (!weekendPredicate(current)) {\n businessDaysCounted++;\n }\n if (businessDaysCounted < targetDays) {\n current.setUTCDate(current.getUTCDate() + 1);\n }\n }\n\n return current;\n}\n\n/**\n * Calculate start date by subtracting N business days from end date.\n * Returns a Date object.\n */\nexport function subtractBusinessDays(\n endDate: string | Date,\n businessDays: number,\n weekendPredicate: (date: Date) => boolean\n): Date {\n const end = typeof endDate === 'string'\n ? new Date(`${endDate.split('T')[0]}T00:00:00.000Z`)\n : normalizeUTCDate(endDate);\n const current = new Date(end);\n let targetDays = Math.max(1, businessDays);\n let businessDaysCounted = 0;\n\n while (businessDaysCounted < targetDays) {\n if (!weekendPredicate(current)) {\n businessDaysCounted++;\n }\n if (businessDaysCounted < targetDays) {\n current.setUTCDate(current.getUTCDate() - 1);\n }\n }\n\n return current;\n}\n\n/**\n * Snap a date to the nearest working day in the given direction.\n */\nexport function alignToWorkingDay(\n date: Date,\n direction: 1 | -1,\n weekendPredicate: (date: Date) => boolean\n): Date {\n const current = normalizeUTCDate(date);\n\n while (weekendPredicate(current)) {\n current.setUTCDate(current.getUTCDate() + direction);\n }\n\n return current;\n}\n\n/**\n * Get task duration in days (inclusive).\n * If businessDays mode, counts business days using weekendPredicate.\n * Otherwise, counts calendar days.\n */\nexport function getTaskDuration(\n startDate: string | Date,\n endDate: string | Date,\n businessDays: boolean = false,\n weekendPredicate?: (date: Date) => boolean\n): number {\n const start = parseDateOnly(startDate);\n const end = parseDateOnly(endDate);\n\n if (businessDays && weekendPredicate) {\n return getBusinessDaysCount(start, end, weekendPredicate);\n }\n\n return Math.max(1, Math.round((end.getTime() - start.getTime()) / DAY_MS) + 1);\n}\n","/**\n * Dependency calculation functions.\n * Moved from dependencyUtils.ts — verbatim implementations.\n * Zero React/DOM/date-fns imports.\n */\n\nimport type { LinkType, TaskDependency } from './types';\nimport {\n getBusinessDayOffset,\n shiftBusinessDayOffset,\n DAY_MS,\n getTaskDuration,\n} from './dateMath';\n\n/**\n * Get lag value from dependency, defaulting to 0.\n */\nexport function getDependencyLag(dep: Pick<TaskDependency, 'lag'>): number {\n return Number.isFinite(dep.lag) ? dep.lag : 0;\n}\n\n/**\n * Normalize lag for FS links — clamp to >= -predecessorDuration.\n */\nexport function normalizeDependencyLag(\n linkType: LinkType,\n lag: number,\n predecessorStart: Date,\n predecessorEnd: Date,\n businessDays: boolean = false,\n weekendPredicate?: (date: Date) => boolean\n): number {\n if (linkType !== 'FS') {\n return lag;\n }\n\n const predecessorDuration = getTaskDuration(\n predecessorStart,\n predecessorEnd,\n businessDays,\n weekendPredicate\n );\n\n return Math.max(-predecessorDuration, lag);\n}\n\n/**\n * Compute lag (in days) from actual predecessor/successor dates.\n * This is the single source of truth for lag semantics.\n *\n * Semantics (lag=0 = natural, gap-free connection):\n * - FS: lag = succStart - predEnd - 1 (adjacent days = 0)\n * - SS: lag = succStart - predStart\n * - FF: lag = succEnd - predEnd\n * - SF: lag = succEnd - predStart + 1 (symmetric to FS)\n */\nexport function computeLagFromDates(\n linkType: LinkType,\n predStart: Date,\n predEnd: Date,\n succStart: Date,\n succEnd: Date,\n businessDays: boolean = false,\n weekendPredicate?: (date: Date) => boolean\n): number {\n const pS = Date.UTC(predStart.getUTCFullYear(), predStart.getUTCMonth(), predStart.getUTCDate());\n const pE = Date.UTC(predEnd.getUTCFullYear(), predEnd.getUTCMonth(), predEnd.getUTCDate());\n const sS = Date.UTC(succStart.getUTCFullYear(), succStart.getUTCMonth(), succStart.getUTCDate());\n const sE = Date.UTC(succEnd.getUTCFullYear(), succEnd.getUTCMonth(), succEnd.getUTCDate());\n\n // Calendar days (original logic)\n if (!businessDays || !weekendPredicate) {\n switch (linkType) {\n case 'FS':\n return normalizeDependencyLag(\n linkType,\n Math.round((sS - pE) / DAY_MS) - 1,\n predStart,\n predEnd,\n businessDays,\n weekendPredicate\n );\n case 'SS': return Math.round((sS - pS) / DAY_MS);\n case 'FF': return Math.round((sE - pE) / DAY_MS);\n case 'SF': return Math.round((sE - pS) / DAY_MS) + 1;\n }\n }\n\n const anchorDate = linkType === 'SS' || linkType === 'SF' ? predStart : predEnd;\n const targetDate = linkType === 'FS' || linkType === 'SS' ? succStart : succEnd;\n const businessOffset = getBusinessDayOffset(anchorDate, targetDate, weekendPredicate);\n\n switch (linkType) {\n case 'FS':\n return normalizeDependencyLag(\n linkType,\n businessOffset - 1,\n predStart,\n predEnd,\n businessDays,\n weekendPredicate\n );\n case 'SS': return businessOffset;\n case 'FF': return businessOffset;\n case 'SF': return businessOffset + 1;\n }\n}\n\n/**\n * Calculate successor date based on predecessor dates, link type, and lag.\n *\n * Link type semantics:\n * - FS: Successor start = Predecessor end + lag + 1 day (lag=0 -> next day)\n * - SS: Successor start = Predecessor start + lag\n * - FF: Successor end = Predecessor end + lag\n * - SF: Successor end = Predecessor start + lag - 1 day (lag=0 -> day before)\n */\nexport function calculateSuccessorDate(\n predecessorStart: Date,\n predecessorEnd: Date,\n linkType: LinkType,\n lag: number = 0,\n businessDays: boolean = false,\n weekendPredicate?: (date: Date) => boolean\n): Date {\n const normalizedLag = normalizeDependencyLag(\n linkType,\n lag,\n predecessorStart,\n predecessorEnd,\n businessDays,\n weekendPredicate\n );\n\n // Calendar days (original logic)\n if (!businessDays || !weekendPredicate) {\n switch (linkType) {\n case 'FS':\n return new Date(predecessorEnd.getTime() + (normalizedLag + 1) * DAY_MS);\n case 'SS':\n return new Date(predecessorStart.getTime() + normalizedLag * DAY_MS);\n case 'FF':\n return new Date(predecessorEnd.getTime() + normalizedLag * DAY_MS);\n case 'SF':\n return new Date(predecessorStart.getTime() + (normalizedLag - 1) * DAY_MS);\n }\n }\n\n const anchorDate = (linkType === 'FS' || linkType === 'FF') ? predecessorEnd : predecessorStart;\n let offset: number;\n switch (linkType) {\n case 'FS':\n offset = normalizedLag + 1;\n break;\n case 'SS':\n offset = normalizedLag;\n break;\n case 'FF':\n offset = normalizedLag;\n break;\n case 'SF':\n offset = normalizedLag - 1;\n break;\n }\n return shiftBusinessDayOffset(anchorDate, offset, weekendPredicate);\n}\n","/**\n * Hierarchy scheduling functions.\n * Moved from dependencyUtils.ts — verbatim implementations.\n * Zero React/DOM/date-fns imports.\n */\n\nimport type { Task } from './types';\n\n/**\n * Get all child tasks of a parent task.\n * Returns tasks where task.parentId === parentId.\n */\nexport function getChildren(parentId: string, tasks: Task[]): Task[] {\n return tasks.filter(t => (t as any).parentId === parentId);\n}\n\n/**\n * Check if a task is a parent (has children).\n * Returns true if any task has this task as parentId.\n */\nexport function isTaskParent(taskId: string, tasks: Task[]): boolean {\n return tasks.some(t => (t as any).parentId === taskId);\n}\n\n/**\n * Compute parent task dates from children.\n * Returns { startDate, endDate } where:\n * - startDate = min(children.startDate) or own startDate if no children\n * - endDate = max(children.endDate) or own endDate if no children\n */\nexport function computeParentDates(parentId: string, tasks: Task[]): { startDate: Date; endDate: Date } {\n const children = getChildren(parentId, tasks);\n\n if (children.length === 0) {\n const parent = tasks.find(t => t.id === parentId);\n const start = parent ? new Date(parent.startDate) : new Date();\n const end = parent ? new Date(parent.endDate) : new Date();\n return { startDate: start, endDate: end };\n }\n\n const startDates = children.map(c => new Date(c.startDate));\n const endDates = children.map(c => new Date(c.endDate));\n\n const minTime = Math.min(...startDates.map(d => d.getTime()));\n const maxTime = Math.max(...endDates.map(d => d.getTime()));\n\n return {\n startDate: new Date(minTime),\n endDate: new Date(maxTime),\n };\n}\n\n/**\n * Compute parent task progress from children (weighted average by duration).\n * Returns 0 if no children.\n * Progress is rounded to 1 decimal place.\n */\nexport function computeParentProgress(parentId: string, tasks: Task[]): number {\n const children = getChildren(parentId, tasks);\n\n if (children.length === 0) {\n return 0;\n }\n\n const DAY_MS = 24 * 60 * 60 * 1000;\n let totalWeight = 0;\n let weightedSum = 0;\n\n for (const child of children) {\n const start = new Date(child.startDate).getTime();\n const end = new Date(child.endDate).getTime();\n // Inclusive duration: (end - start + 1 day) / DAY_MS\n const duration = (end - start + DAY_MS) / DAY_MS;\n const progress = (child.progress ?? 0);\n\n totalWeight += duration;\n weightedSum += duration * progress;\n }\n\n if (totalWeight === 0) {\n return 0;\n }\n\n // Round to 1 decimal place\n return Math.round((weightedSum / totalWeight) * 10) / 10;\n}\n\n/**\n * Get all descendant tasks of a parent task (transitive closure of children).\n * Returns all tasks where task.parentId is in the hierarchy of the parent.\n */\nexport function getAllDescendants(parentId: string, tasks: Task[]): Task[] {\n const descendants: Task[] = [];\n const visited = new Set<string>();\n\n function collectChildren(taskId: string) {\n if (visited.has(taskId)) return;\n visited.add(taskId);\n\n const children = getChildren(taskId, tasks);\n for (const child of children) {\n descendants.push(child);\n collectChildren(child.id);\n }\n }\n\n collectChildren(parentId);\n return descendants;\n}\n\n/**\n * Get all dependency edges for rendering.\n * Returns array of { predecessorId, successorId, type, lag }\n */\nexport function getAllDependencyEdges(tasks: Task[]): Array<{\n predecessorId: string;\n successorId: string;\n type: 'FS' | 'SS' | 'FF' | 'SF';\n lag: number;\n}> {\n const edges: Array<{ predecessorId: string; successorId: string; type: 'FS' | 'SS' | 'FF' | 'SF'; lag: number }> = [];\n\n for (const task of tasks) {\n if (task.dependencies) {\n for (const dep of task.dependencies) {\n edges.push({\n predecessorId: dep.taskId,\n successorId: task.id,\n type: dep.type,\n lag: dep.lag ?? 0,\n });\n }\n }\n }\n\n return edges;\n}\n\n/**\n * Remove dependencies between two tasks in both directions.\n */\nexport function removeDependenciesBetweenTasks(\n taskId1: string,\n taskId2: string,\n tasks: Task[]\n): Task[] {\n return tasks.map(task => {\n if (task.id === taskId1 || task.id === taskId2) {\n if (!task.dependencies) return task;\n const otherTaskId = task.id === taskId1 ? taskId2 : taskId1;\n const filteredDependencies = task.dependencies.filter(dep => dep.taskId !== otherTaskId);\n if (filteredDependencies.length === task.dependencies.length) {\n return task;\n }\n return {\n ...task,\n dependencies: filteredDependencies.length > 0 ? filteredDependencies : undefined,\n };\n }\n return task;\n });\n}\n\n/**\n * Find the parent ID of a task.\n */\nexport function findParentId(taskId: string, tasks: Task[]): string | undefined {\n const task = tasks.find(t => t.id === taskId);\n return task?.parentId;\n}\n\n/**\n * Returns true when ancestorId is an ancestor of taskId in the current hierarchy.\n */\nexport function isAncestorTask(ancestorId: string, taskId: string, tasks: Task[]): boolean {\n const taskById = new Map(tasks.map(task => [task.id, task]));\n const visited = new Set<string>();\n let current = taskById.get(taskId);\n\n while (current?.parentId) {\n if (current.parentId === ancestorId) {\n return true;\n }\n\n if (visited.has(current.parentId)) {\n return false;\n }\n\n visited.add(current.parentId);\n current = taskById.get(current.parentId);\n }\n\n return false;\n}\n\n/**\n * Returns true when tasks are in the same ancestry chain.\n */\nexport function areTasksHierarchicallyRelated(taskId1: string, taskId2: string, tasks: Task[]): boolean {\n if (taskId1 === taskId2) {\n return true;\n }\n\n return isAncestorTask(taskId1, taskId2, tasks) || isAncestorTask(taskId2, taskId1, tasks);\n}\n","/**\n * High-level schedule command functions.\n * Moved from dependencyUtils.ts — verbatim implementations.\n * Zero React/DOM/date-fns imports.\n */\n\nimport type { Task } from './types';\nimport {\n normalizeUTCDate,\n parseDateOnly,\n addBusinessDays,\n subtractBusinessDays,\n alignToWorkingDay,\n getTaskDuration,\n getBusinessDaysCount,\n} from './dateMath';\nimport {\n calculateSuccessorDate,\n getDependencyLag,\n normalizeDependencyLag,\n computeLagFromDates,\n} from './dependencies';\n\n// Re-export for backward compat — these live in dateMath now\nexport { alignToWorkingDay, getTaskDuration };\n\n/**\n * Build a task range (start/end dates) from a start date and duration.\n */\nexport function buildTaskRangeFromStart(\n startDate: Date,\n duration: number,\n businessDays: boolean = false,\n weekendPredicate?: (date: Date) => boolean,\n snapDirection: 1 | -1 = 1\n): { start: Date; end: Date } {\n const normalizedStart = businessDays && weekendPredicate\n ? alignToWorkingDay(startDate, snapDirection, weekendPredicate)\n : normalizeUTCDate(startDate);\n\n if (businessDays && weekendPredicate) {\n return {\n start: normalizedStart,\n end: parseDateOnly(addBusinessDays(normalizedStart, duration, weekendPredicate)),\n };\n }\n\n const DAY_MS = 24 * 60 * 60 * 1000;\n return {\n start: normalizedStart,\n end: new Date(normalizedStart.getTime() + (Math.max(1, duration) - 1) * DAY_MS),\n };\n}\n\n/**\n * Build a task range (start/end dates) from an end date and duration.\n */\nexport function buildTaskRangeFromEnd(\n endDate: Date,\n duration: number,\n businessDays: boolean = false,\n weekendPredicate?: (date: Date) => boolean,\n snapDirection: 1 | -1 = -1\n): { start: Date; end: Date } {\n const normalizedEnd = businessDays && weekendPredicate\n ? alignToWorkingDay(endDate, snapDirection, weekendPredicate)\n : normalizeUTCDate(endDate);\n\n if (businessDays && weekendPredicate) {\n return {\n start: parseDateOnly(subtractBusinessDays(normalizedEnd, duration, weekendPredicate)),\n end: normalizedEnd,\n };\n }\n\n const DAY_MS = 24 * 60 * 60 * 1000;\n return {\n start: new Date(normalizedEnd.getTime() - (Math.max(1, duration) - 1) * DAY_MS),\n end: normalizedEnd,\n };\n}\n\n/**\n * Move a task range to a new start date, preserving duration.\n */\nexport function moveTaskRange(\n originalStart: string | Date,\n originalEnd: string | Date,\n proposedStart: Date,\n businessDays: boolean = false,\n weekendPredicate?: (date: Date) => boolean,\n snapDirection: 1 | -1 = 1\n): { start: Date; end: Date } {\n return buildTaskRangeFromStart(\n proposedStart,\n getTaskDuration(originalStart, originalEnd, businessDays, weekendPredicate),\n businessDays,\n weekendPredicate,\n snapDirection\n );\n}\n\n/**\n * Clamp task range start date based on incoming FS dependencies.\n */\nexport function clampTaskRangeForIncomingFS(\n task: Pick<Task, 'dependencies'>,\n proposedStart: Date,\n proposedEnd: Date,\n allTasks: Task[],\n businessDays: boolean = false,\n weekendPredicate?: (date: Date) => boolean\n): { start: Date; end: Date } {\n if (!task.dependencies?.length) {\n return { start: proposedStart, end: proposedEnd };\n }\n\n let minAllowedStart: Date | null = null;\n\n for (const dep of task.dependencies) {\n if (dep.type !== 'FS') {\n continue;\n }\n\n const predecessor = allTasks.find(candidate => candidate.id === dep.taskId);\n if (!predecessor) {\n continue;\n }\n\n const predecessorStart = parseDateOnly(predecessor.startDate);\n const predecessorEnd = parseDateOnly(predecessor.endDate);\n const predecessorDuration = getTaskDuration(\n predecessorStart,\n predecessorEnd,\n businessDays,\n weekendPredicate\n );\n const candidateMinStart = calculateSuccessorDate(\n predecessorStart,\n predecessorEnd,\n 'FS',\n -predecessorDuration,\n businessDays,\n weekendPredicate\n );\n\n if (!minAllowedStart || candidateMinStart.getTime() > minAllowedStart.getTime()) {\n minAllowedStart = candidateMinStart;\n }\n }\n\n if (!minAllowedStart || proposedStart.getTime() >= minAllowedStart.getTime()) {\n return { start: proposedStart, end: proposedEnd };\n }\n\n return buildTaskRangeFromStart(\n minAllowedStart,\n getTaskDuration(proposedStart, proposedEnd, businessDays, weekendPredicate),\n businessDays,\n weekendPredicate\n );\n}\n\n/**\n * Recalculate incoming dependency lags after a task's dates change.\n */\nexport function recalculateIncomingLags(\n task: Task,\n newStartDate: Date,\n newEndDate: Date,\n allTasks: Task[],\n businessDays: boolean = false,\n weekendPredicate?: (date: Date) => boolean\n): NonNullable<Task['dependencies']> {\n if (!task.dependencies) return [];\n return task.dependencies.map(dep => {\n const predecessor = allTasks.find(candidate => candidate.id === dep.taskId);\n if (!predecessor) {\n return { ...dep, lag: getDependencyLag(dep) };\n }\n\n const predecessorStart = new Date(predecessor.startDate as string);\n const predecessorEnd = new Date(predecessor.endDate as string);\n const nextLag = computeLagFromDates(\n dep.type,\n predecessorStart,\n predecessorEnd,\n newStartDate,\n newEndDate,\n businessDays,\n weekendPredicate\n );\n\n return { ...dep, lag: nextLag };\n });\n}\n\n","/**\n * Cascade engine functions.\n * Moved from dependencyUtils.ts — verbatim implementations.\n * Zero React/DOM/date-fns imports.\n */\n\nimport type { Task, LinkType } from './types';\nimport {\n normalizeUTCDate,\n getTaskDuration,\n alignToWorkingDay,\n} from './dateMath';\nimport {\n calculateSuccessorDate,\n getDependencyLag,\n} from './dependencies';\nimport {\n getChildren,\n isTaskParent,\n computeParentDates,\n} from './hierarchy';\nimport {\n buildTaskRangeFromStart,\n buildTaskRangeFromEnd,\n moveTaskRange,\n} from './commands';\n\n/**\n * Get successor tasks of a dragged task using BFS, filtered by link type(s).\n */\nexport function getSuccessorChain(\n draggedTaskId: string,\n allTasks: Task[],\n linkTypes: LinkType[] = ['FS']\n): Task[] {\n const successorMap = new Map<string, string[]>();\n for (const task of allTasks) {\n successorMap.set(task.id, []);\n }\n for (const task of allTasks) {\n if (!task.dependencies) continue;\n for (const dep of task.dependencies) {\n if (linkTypes.includes(dep.type)) {\n const list = successorMap.get(dep.taskId) ?? [];\n list.push(task.id);\n successorMap.set(dep.taskId, list);\n }\n }\n }\n\n const taskById = new Map(allTasks.map(t => [t.id, t]));\n const visited = new Set<string>();\n const queue: string[] = [draggedTaskId];\n const chain: Task[] = [];\n visited.add(draggedTaskId);\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n const successors = successorMap.get(current) ?? [];\n for (const sid of successors) {\n if (!visited.has(sid)) {\n visited.add(sid);\n const t = taskById.get(sid);\n if (t) {\n chain.push(t);\n queue.push(sid);\n }\n }\n }\n }\n\n return chain;\n}\n\n/**\n * Cascade successors by actual link constraints (BFS, constraint-based).\n */\nexport function cascadeByLinks(\n movedTaskId: string,\n newStart: Date,\n newEnd: Date,\n allTasks: Task[],\n skipChildCascade: boolean = false\n): Task[] {\n const taskById = new Map(allTasks.map(t => [t.id, t]));\n\n const updatedDates = new Map<string, { start: Date; end: Date }>();\n updatedDates.set(movedTaskId, { start: newStart, end: newEnd });\n\n const result: Task[] = [];\n const queue: string[] = [movedTaskId];\n const visited = new Set<string>([movedTaskId]);\n\n while (queue.length > 0) {\n const currentId = queue.shift()!;\n const { start: predStart, end: predEnd } = updatedDates.get(currentId)!;\n\n if (!skipChildCascade) {\n const children = getChildren(currentId, allTasks);\n for (const child of children) {\n if (visited.has(child.id) || child.locked) continue;\n\n const origStart = new Date(child.startDate as string);\n const origEnd = new Date(child.endDate as string);\n const durationMs = origEnd.getTime() - origStart.getTime();\n\n const parentOrig = taskById.get(currentId)!;\n const parentOrigStart = new Date(parentOrig.startDate as string);\n const parentOrigEnd = new Date(parentOrig.endDate as string);\n\n const parentStartDelta = predStart.getTime() - parentOrigStart.getTime();\n const parentEndDelta = predEnd.getTime() - parentOrigEnd.getTime();\n\n const newChildStart = new Date(origStart.getTime() + parentStartDelta);\n const newChildEnd = new Date(origEnd.getTime() + parentEndDelta);\n\n visited.add(child.id);\n updatedDates.set(child.id, { start: newChildStart, end: newChildEnd });\n result.push({\n ...child,\n startDate: newChildStart.toISOString().split('T')[0],\n endDate: newChildEnd.toISOString().split('T')[0],\n });\n queue.push(child.id);\n }\n }\n\n for (const task of allTasks) {\n if (visited.has(task.id) || !task.dependencies || task.locked) continue;\n\n for (const dep of task.dependencies) {\n if (dep.taskId !== currentId) continue;\n\n const orig = taskById.get(task.id)!;\n const origStart = new Date(orig.startDate as string);\n const origEnd = new Date(orig.endDate as string);\n const duration = getTaskDuration(origStart, origEnd);\n const constraintDate = calculateSuccessorDate(predStart, predEnd, dep.type, getDependencyLag(dep));\n\n let newSuccStart: Date;\n let newSuccEnd: Date;\n\n if (dep.type === 'FS' || dep.type === 'SS') {\n ({ start: newSuccStart, end: newSuccEnd } = buildTaskRangeFromStart(constraintDate, duration));\n } else {\n ({ start: newSuccStart, end: newSuccEnd } = buildTaskRangeFromEnd(constraintDate, duration));\n }\n\n visited.add(task.id);\n updatedDates.set(task.id, { start: newSuccStart, end: newSuccEnd });\n result.push({\n ...task,\n startDate: newSuccStart.toISOString().split('T')[0],\n endDate: newSuccEnd.toISOString().split('T')[0],\n });\n queue.push(task.id);\n break;\n }\n }\n }\n\n return result;\n}\n\n/**\n * Get transitive closure of successors for cascading.\n */\nexport function getTransitiveCascadeChain(\n changedTaskId: string,\n allTasks: Task[],\n firstLevelLinkTypes: LinkType[]\n): Task[] {\n const allTypesSuccessorMap = new Map<string, Task[]>();\n for (const task of allTasks) {\n allTypesSuccessorMap.set(task.id, []);\n }\n for (const task of allTasks) {\n if (!task.dependencies) continue;\n for (const dep of task.dependencies) {\n const list = allTypesSuccessorMap.get(dep.taskId) ?? [];\n list.push(task);\n allTypesSuccessorMap.set(dep.taskId, list);\n }\n }\n\n const directChildren = getChildren(changedTaskId, allTasks);\n const directSuccessors = getSuccessorChain(changedTaskId, allTasks, firstLevelLinkTypes);\n const initialChain = [...directChildren, ...directSuccessors].filter((task, index, arr) =>\n arr.findIndex(candidate => candidate.id === task.id) === index\n );\n\n const chain = [...initialChain];\n const visited = new Set<string>([changedTaskId, ...initialChain.map(t => t.id)]);\n const queue = [...initialChain];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n\n const children = getChildren(current.id, allTasks);\n for (const child of children) {\n if (!visited.has(child.id)) {\n visited.add(child.id);\n chain.push(child);\n queue.push(child);\n }\n }\n\n const successors = allTypesSuccessorMap.get(current.id) ?? [];\n for (const successor of successors) {\n if (!visited.has(successor.id)) {\n visited.add(successor.id);\n chain.push(successor);\n queue.push(successor);\n }\n }\n }\n\n return chain;\n}\n\n/**\n * Arrival mode for universal cascade BFS entries.\n */\ntype ArrivalMode = 'direct' | 'child-delta' | 'parent-recalc' | 'dependency';\n\n/**\n * Universal cascade engine that propagates a moved task's new position through\n * the entire dependency+hierarchy graph using BFS with change detection.\n */\nexport function universalCascade(\n movedTask: Task,\n newStart: Date,\n newEnd: Date,\n allTasks: Task[],\n businessDays: boolean = false,\n weekendPredicate?: (date: Date) => boolean\n): Task[] {\n const taskById = new Map(allTasks.map(t => [t.id, t]));\n\n const updatedDates = new Map<string, { start: Date; end: Date }>();\n updatedDates.set(movedTask.id, { start: newStart, end: newEnd });\n\n const resultMap = new Map<string, Task>();\n resultMap.set(movedTask.id, {\n ...movedTask,\n startDate: newStart.toISOString().split('T')[0],\n endDate: newEnd.toISOString().split('T')[0],\n });\n\n const queue: Array<[string, ArrivalMode]> = [[movedTask.id, 'direct']];\n\n const childShifted = new Set<string>();\n\n let iterations = 0;\n const MAX_ITERATIONS = allTasks.length * 3;\n\n while (queue.length > 0 && iterations < MAX_ITERATIONS) {\n iterations++;\n const [currentId, arrivalMode] = queue.shift()!;\n const { start: currStart, end: currEnd } = updatedDates.get(currentId)!;\n const currentOriginal = taskById.get(currentId)!;\n\n // RULE 1: Hierarchy children follow their parent\n if (arrivalMode !== 'parent-recalc') {\n const children = getChildren(currentId, allTasks);\n for (const child of children) {\n if (childShifted.has(child.id) || child.locked) continue;\n\n const parentOrigStart = new Date(currentOriginal.startDate as string);\n const parentOrigEnd = new Date(currentOriginal.endDate as string);\n\n const childOrigStart = new Date(child.startDate as string);\n const childOrigEnd = new Date(child.endDate as string);\n\n const startDeltaMs = currStart.getTime() - parentOrigStart.getTime();\n const endDeltaMs = currEnd.getTime() - parentOrigEnd.getTime();\n\n let childNewStart: Date;\n let childNewEnd: Date;\n\n if (businessDays && weekendPredicate) {\n const proposedStart = new Date(childOrigStart.getTime() + startDeltaMs);\n const snapDirection: 1 | -1 = currStart.getTime() >= parentOrigStart.getTime() ? 1 : -1;\n const movedRange = moveTaskRange(\n child.startDate,\n child.endDate,\n proposedStart,\n true,\n weekendPredicate,\n snapDirection\n );\n childNewStart = movedRange.start;\n childNewEnd = movedRange.end;\n } else {\n childNewStart = new Date(childOrigStart.getTime() + startDeltaMs);\n childNewEnd = new Date(childOrigEnd.getTime() + endDeltaMs);\n }\n\n const prev = updatedDates.get(child.id);\n if (prev && prev.start.getTime() === childNewStart.getTime() && prev.end.getTime() === childNewEnd.getTime()) {\n continue;\n }\n\n updatedDates.set(child.id, { start: childNewStart, end: childNewEnd });\n childShifted.add(child.id);\n queue.push([child.id, 'child-delta']);\n resultMap.set(child.id, {\n ...child,\n startDate: childNewStart.toISOString().split('T')[0],\n endDate: childNewEnd.toISOString().split('T')[0],\n });\n }\n }\n\n // RULE 2: Parent task is recomputed from its children\n const parentId = (currentOriginal as any).parentId as string | undefined;\n if (parentId) {\n const parent = taskById.get(parentId);\n if (parent && !parent.locked) {\n const siblings = getChildren(parentId, allTasks);\n\n const siblingPositions = siblings.map(sib => {\n if (updatedDates.has(sib.id)) return updatedDates.get(sib.id)!;\n return { start: new Date(sib.startDate as string), end: new Date(sib.endDate as string) };\n });\n\n const minStart = new Date(Math.min(...siblingPositions.map(p => p.start.getTime())));\n const maxEnd = new Date(Math.max(...siblingPositions.map(p => p.end.getTime())));\n\n const prev = updatedDates.get(parentId);\n if (!prev || prev.start.getTime() !== minStart.getTime() || prev.end.getTime() !== maxEnd.getTime()) {\n updatedDates.set(parentId, { start: minStart, end: maxEnd });\n queue.push([parentId, 'parent-recalc']);\n resultMap.set(parentId, {\n ...parent,\n startDate: minStart.toISOString().split('T')[0],\n endDate: maxEnd.toISOString().split('T')[0],\n });\n }\n }\n }\n\n // RULE 3: Dependency successors are repositioned\n for (const task of allTasks) {\n if (task.locked || !task.dependencies) continue;\n\n const dep = task.dependencies.find(d => d.taskId === currentId);\n if (!dep) continue;\n\n const origStart = new Date(task.startDate as string);\n const origEnd = new Date(task.endDate as string);\n const constraintDate = calculateSuccessorDate(\n currStart, currEnd, dep.type, getDependencyLag(dep),\n businessDays, weekendPredicate\n );\n\n let succNewStart: Date;\n let succNewEnd: Date;\n const duration = getTaskDuration(origStart, origEnd, businessDays, weekendPredicate);\n\n if (dep.type === 'FS' || dep.type === 'SS') {\n ({ start: succNewStart, end: succNewEnd } = buildTaskRangeFromStart(\n constraintDate,\n duration,\n businessDays,\n weekendPredicate\n ));\n } else {\n ({ start: succNewStart, end: succNewEnd } = buildTaskRangeFromEnd(\n constraintDate,\n duration,\n businessDays,\n weekendPredicate\n ));\n }\n\n const prev = updatedDates.get(task.id);\n if (prev && prev.start.getTime() === succNewStart.getTime() && prev.end.getTime() === succNewEnd.getTime()) {\n continue;\n }\n\n updatedDates.set(task.id, { start: succNewStart, end: succNewEnd });\n queue.push([task.id, 'dependency']);\n resultMap.set(task.id, {\n ...task,\n startDate: succNewStart.toISOString().split('T')[0],\n endDate: succNewEnd.toISOString().split('T')[0],\n });\n }\n }\n\n return Array.from(resultMap.values());\n}\n\n/**\n * Recalculate all task dates when switching between business/calendar day modes.\n */\nexport function reflowTasksOnModeSwitch(\n sourceTasks: Task[],\n toBusinessDays: boolean,\n weekendPredicate: (date: Date) => boolean\n): Task[] {\n const fromBusinessDays = !toBusinessDays;\n let tasks: Task[] = sourceTasks.map(t => ({ ...t }));\n\n const toISO = (d: Date) => d.toISOString().split('T')[0];\n\n for (const task of tasks) {\n if (isTaskParent(task.id, tasks)) continue;\n\n const start = normalizeUTCDate(new Date(`${task.startDate}T00:00:00.000Z`));\n const duration = getTaskDuration(task.startDate, task.endDate, fromBusinessDays, weekendPredicate);\n\n let range: { start: Date; end: Date };\n if (toBusinessDays) {\n const alignedStart = alignToWorkingDay(start, 1, weekendPredicate);\n range = buildTaskRangeFromStart(alignedStart, duration, true, weekendPredicate);\n } else {\n range = buildTaskRangeFromStart(start, duration, false);\n }\n\n task.startDate = toISO(range.start);\n task.endDate = toISO(range.end);\n }\n\n for (const task of tasks) {\n if (!isTaskParent(task.id, tasks)) continue;\n const { startDate, endDate } = computeParentDates(task.id, tasks);\n task.startDate = toISO(startDate);\n task.endDate = toISO(endDate);\n }\n\n if (toBusinessDays) {\n const rootSeeds = tasks.filter(\n t => !(t as any).parentId && (!t.dependencies || t.dependencies.length === 0)\n );\n\n for (const seed of rootSeeds) {\n const current = tasks.find(t => t.id === seed.id)!;\n const start = new Date(`${current.startDate}T00:00:00.000Z`);\n const end = new Date(`${current.endDate}T00:00:00.000Z`);\n\n const cascaded = universalCascade(current, start, end, tasks, toBusinessDays, weekendPredicate);\n const updates = new Map(cascaded.map((t): [string, Task] => [t.id, t]));\n tasks = tasks.map(t => updates.get(t.id) ?? t);\n }\n }\n\n return tasks;\n}\n","/**\n * Command-level scheduling API.\n * High-level functions that compose low-level scheduling primitives.\n * Zero React/DOM/date-fns imports.\n */\n\nimport type { Task, ScheduleCommandResult, ScheduleCommandOptions } from './types';\nimport { moveTaskRange, recalculateIncomingLags, buildTaskRangeFromEnd, buildTaskRangeFromStart, getTaskDuration } from './commands';\nimport { universalCascade } from './cascade';\nimport { parseDateOnly } from './dateMath';\nimport { calculateSuccessorDate, getDependencyLag } from './dependencies';\nimport { computeParentDates, isTaskParent } from './hierarchy';\n\nfunction toIsoDate(date: Date): string {\n return date.toISOString().split('T')[0];\n}\n\nfunction createChangedResult(snapshot: Task[], nextTasks: Task[]): ScheduleCommandResult {\n const originalById = new Map(snapshot.map(task => [task.id, task]));\n const changedTasks = nextTasks.filter(task => JSON.stringify(originalById.get(task.id)) !== JSON.stringify(task));\n\n return {\n changedTasks,\n changedIds: changedTasks.map(task => task.id),\n };\n}\n\n/**\n * Move a task to a new start date with cascade and lag recalculation.\n * Identical to manual composition: moveTaskRange -> recalculateIncomingLags -> universalCascade.\n */\nexport function moveTaskWithCascade(\n taskId: string,\n newStart: Date,\n snapshot: Task[],\n options?: ScheduleCommandOptions\n): ScheduleCommandResult {\n const task = snapshot.find(t => t.id === taskId);\n if (!task) {\n return { changedTasks: [], changedIds: [] };\n }\n\n const businessDays = options?.businessDays ?? false;\n const weekendPredicate = options?.weekendPredicate;\n\n // Step 1: Calculate new range preserving duration\n const newRange = moveTaskRange(\n task.startDate,\n task.endDate,\n newStart,\n businessDays,\n weekendPredicate\n );\n\n // Step 2: Recalculate incoming dependency lags\n const updatedDependencies = recalculateIncomingLags(\n task,\n newRange.start,\n newRange.end,\n snapshot,\n businessDays,\n weekendPredicate\n );\n\n // Step 3: Create moved task with updated deps\n const movedTask: Task = {\n ...task,\n startDate: newRange.start.toISOString().split('T')[0],\n endDate: newRange.end.toISOString().split('T')[0],\n dependencies: updatedDependencies,\n };\n\n // Step 4: Cascade through dependency graph\n if (options?.skipCascade) {\n return {\n changedTasks: [movedTask],\n changedIds: [movedTask.id],\n };\n }\n\n const cascadeResult = universalCascade(\n movedTask,\n newRange.start,\n newRange.end,\n snapshot,\n businessDays,\n weekendPredicate\n );\n\n // Merge: movedTask + cascade results\n const resultMap = new Map<string, Task>();\n resultMap.set(movedTask.id, movedTask);\n for (const t of cascadeResult) {\n resultMap.set(t.id, t);\n }\n\n const changedTasks = Array.from(resultMap.values());\n return {\n changedTasks,\n changedIds: changedTasks.map(t => t.id),\n };\n}\n\n/**\n * Resize a task by changing its start or end date.\n * anchor='end': new end date, start stays fixed.\n * anchor='start': new start date, end stays fixed.\n */\nexport function resizeTaskWithCascade(\n taskId: string,\n anchor: 'start' | 'end',\n newDate: Date,\n snapshot: Task[],\n options?: ScheduleCommandOptions\n): ScheduleCommandResult {\n const task = snapshot.find(t => t.id === taskId);\n if (!task) {\n return { changedTasks: [], changedIds: [] };\n }\n\n const businessDays = options?.businessDays ?? false;\n const weekendPredicate = options?.weekendPredicate;\n\n const originalStart = parseDateOnly(task.startDate);\n const originalEnd = parseDateOnly(task.endDate);\n let newRange: { start: Date; end: Date };\n\n if (anchor === 'end') {\n // anchor='end': new end date, start stays fixed\n newRange = { start: originalStart, end: newDate };\n } else {\n // anchor='start': new start date, end stays fixed\n newRange = { start: newDate, end: originalEnd };\n }\n\n // Recalculate lags\n const updatedDependencies = recalculateIncomingLags(\n task,\n newRange.start,\n newRange.end,\n snapshot,\n businessDays,\n weekendPredicate\n );\n\n // Create resized task\n const resizedTask: Task = {\n ...task,\n startDate: newRange.start.toISOString().split('T')[0],\n endDate: newRange.end.toISOString().split('T')[0],\n dependencies: updatedDependencies,\n };\n\n if (options?.skipCascade) {\n return {\n changedTasks: [resizedTask],\n changedIds: [resizedTask.id],\n };\n }\n\n // Cascade through dependency graph\n const cascadeResult = universalCascade(\n resizedTask,\n newRange.start,\n newRange.end,\n snapshot,\n businessDays,\n weekendPredicate\n );\n\n const resultMap = new Map<string, Task>();\n resultMap.set(resizedTask.id, resizedTask);\n for (const t of cascadeResult) {\n resultMap.set(t.id, t);\n }\n\n const changedTasks = Array.from(resultMap.values());\n return {\n changedTasks,\n changedIds: changedTasks.map(t => t.id),\n };\n}\n\n/**\n * Recalculate a task's dates based on its dependency constraints.\n * Finds all predecessors and computes the most constrained date.\n */\nexport function recalculateTaskFromDependencies(\n taskId: string,\n snapshot: Task[],\n options?: ScheduleCommandOptions\n): ScheduleCommandResult {\n const task = snapshot.find(t => t.id === taskId);\n if (!task) {\n return { changedTasks: [], changedIds: [] };\n }\n\n const businessDays = options?.businessDays ?? false;\n const weekendPredicate = options?.weekendPredicate;\n\n if (!task.dependencies || task.dependencies.length === 0) {\n // No dependencies — return the task as-is\n return {\n changedTasks: [task],\n changedIds: [task.id],\n };\n }\n\n // Find the most constrained start/end based on all predecessors\n let constrainedStart: Date | null = null;\n let constrainedEnd: Date | null = null;\n\n for (const dep of task.dependencies) {\n const predecessor = snapshot.find(t => t.id === dep.taskId);\n if (!predecessor) continue;\n\n const predStart = parseDateOnly(predecessor.startDate);\n const predEnd = parseDateOnly(predecessor.endDate);\n const constraintDate = calculateSuccessorDate(\n predStart,\n predEnd,\n dep.type,\n getDependencyLag(dep),\n businessDays,\n weekendPredicate\n );\n\n const duration = getTaskDuration(\n parseDateOnly(task.startDate),\n parseDateOnly(task.endDate),\n businessDays,\n weekendPredicate\n );\n\n let range: { start: Date; end: Date };\n if (dep.type === 'FS' || dep.type === 'SS') {\n range = buildTaskRangeFromStart(constraintDate, duration, businessDays, weekendPredicate);\n } else {\n range = buildTaskRangeFromEnd(constraintDate, duration, businessDays, weekendPredicate);\n }\n\n // Take the latest start as the effective constraint\n if (!constrainedStart || range.start.getTime() > constrainedStart.getTime()) {\n constrainedStart = range.start;\n constrainedEnd = range.end;\n }\n }\n\n if (!constrainedStart || !constrainedEnd) {\n return {\n changedTasks: [task],\n changedIds: [task.id],\n };\n }\n\n // Recalculate lags for the new position\n const updatedDependencies = recalculateIncomingLags(\n task,\n constrainedStart,\n constrainedEnd,\n snapshot,\n businessDays,\n weekendPredicate\n );\n\n const recalculatedTask: Task = {\n ...task,\n startDate: constrainedStart.toISOString().split('T')[0],\n endDate: constrainedEnd.toISOString().split('T')[0],\n dependencies: updatedDependencies,\n };\n\n if (options?.skipCascade) {\n return {\n changedTasks: [recalculatedTask],\n changedIds: [recalculatedTask.id],\n };\n }\n\n // Cascade through dependency graph\n const cascadeResult = universalCascade(\n recalculatedTask,\n constrainedStart,\n constrainedEnd,\n snapshot,\n businessDays,\n weekendPredicate\n );\n\n const resultMap = new Map<string, Task>();\n resultMap.set(recalculatedTask.id, recalculatedTask);\n for (const t of cascadeResult) {\n resultMap.set(t.id, t);\n }\n\n const changedTasks = Array.from(resultMap.values());\n return {\n changedTasks,\n changedIds: changedTasks.map(t => t.id),\n };\n}\n\n/**\n * Full project schedule recalculation.\n * Recomputes the project against a continuously updated working snapshot.\n * Returns only tasks whose normalized state changed.\n */\nexport function recalculateProjectSchedule(\n snapshot: Task[],\n options?: ScheduleCommandOptions\n): ScheduleCommandResult {\n const businessDays = options?.businessDays ?? false;\n const weekendPredicate = options?.weekendPredicate;\n const workingMap = new Map(snapshot.map(task => [task.id, { ...task }]));\n const indegree = new Map<string, number>();\n const successorIdsByTask = new Map<string, string[]>();\n\n for (const task of snapshot) {\n indegree.set(task.id, 0);\n successorIdsByTask.set(task.id, []);\n }\n\n for (const task of snapshot) {\n for (const dep of task.dependencies ?? []) {\n if (!workingMap.has(dep.taskId)) {\n continue;\n }\n\n indegree.set(task.id, (indegree.get(task.id) ?? 0) + 1);\n successorIdsByTask.get(dep.taskId)?.push(task.id);\n }\n }\n\n const queue = snapshot\n .filter(task => (indegree.get(task.id) ?? 0) === 0)\n .map(task => task.id);\n\n while (queue.length > 0) {\n const currentId = queue.shift()!;\n\n for (const successorId of successorIdsByTask.get(currentId) ?? []) {\n const nextIndegree = (indegree.get(successorId) ?? 0) - 1;\n indegree.set(successorId, nextIndegree);\n\n if (nextIndegree !== 0) {\n continue;\n }\n\n const currentTask = workingMap.get(successorId);\n if (!currentTask || currentTask.locked || !currentTask.dependencies?.length) {\n queue.push(successorId);\n continue;\n }\n\n const duration = getTaskDuration(\n parseDateOnly(currentTask.startDate),\n parseDateOnly(currentTask.endDate),\n businessDays,\n weekendPredicate\n );\n\n let constrainedRange: { start: Date; end: Date } | null = null;\n\n for (const dep of currentTask.dependencies) {\n const predecessor = workingMap.get(dep.taskId);\n if (!predecessor) {\n continue;\n }\n\n const predecessorStart = parseDateOnly(predecessor.startDate);\n const predecessorEnd = parseDateOnly(predecessor.endDate);\n const constraintDate = calculateSuccessorDate(\n predecessorStart,\n predecessorEnd,\n dep.type,\n getDependencyLag(dep),\n businessDays,\n weekendPredicate\n );\n\n const candidateRange = dep.type === 'FS' || dep.type === 'SS'\n ? buildTaskRangeFromStart(constraintDate, duration, businessDays, weekendPredicate)\n : buildTaskRangeFromEnd(constraintDate, duration, businessDays, weekendPredicate);\n\n if (\n !constrainedRange ||\n candidateRange.start.getTime() > constrainedRange.start.getTime() ||\n (\n candidateRange.start.getTime() === constrainedRange.start.getTime() &&\n candidateRange.end.getTime() > constrainedRange.end.getTime()\n )\n ) {\n constrainedRange = candidateRange;\n }\n }\n\n if (!constrainedRange) {\n queue.push(successorId);\n continue;\n }\n\n workingMap.set(successorId, {\n ...currentTask,\n startDate: toIsoDate(constrainedRange.start),\n endDate: toIsoDate(constrainedRange.end),\n });\n queue.push(successorId);\n }\n }\n\n const parentsByDepth = snapshot\n .filter(task => isTaskParent(task.id, snapshot))\n .map(task => {\n let depth = 0;\n let current = task.parentId ? workingMap.get(task.parentId) : undefined;\n while (current) {\n depth++;\n current = current.parentId ? workingMap.get(current.parentId) : undefined;\n }\n return { taskId: task.id, depth };\n })\n .sort((left, right) => right.depth - left.depth);\n\n const workingTasks = () => Array.from(workingMap.values());\n\n for (const { taskId } of parentsByDepth) {\n const parent = workingMap.get(taskId);\n if (!parent || parent.locked) {\n continue;\n }\n\n const { startDate, endDate } = computeParentDates(taskId, workingTasks());\n workingMap.set(taskId, {\n ...parent,\n startDate: toIsoDate(startDate),\n endDate: toIsoDate(endDate),\n });\n }\n\n return createChangedResult(snapshot, Array.from(workingMap.values()));\n}\n","/**\n * Dependency validation and cycle detection.\n * Moved from dependencyUtils.ts — verbatim implementations.\n * Zero React/DOM/date-fns imports.\n */\n\nimport type { Task, DependencyError, ValidationResult } from './types';\nimport { areTasksHierarchicallyRelated } from './hierarchy';\n\n/**\n * Build adjacency list for dependency graph (task -> successors)\n */\nexport function buildAdjacencyList(tasks: Task[]): Map<string, string[]> {\n const graph = new Map<string, string[]>();\n\n for (const task of tasks) {\n const successors: string[] = [];\n\n // Find all tasks that depend on this task (this task is a predecessor)\n for (const otherTask of tasks) {\n if (otherTask.dependencies) {\n for (const dep of otherTask.dependencies) {\n if (dep.taskId === task.id) {\n successors.push(otherTask.id);\n break;\n }\n }\n }\n }\n\n graph.set(task.id, successors);\n }\n\n return graph;\n}\n\n/**\n * Detect circular dependencies using depth-first search\n */\nexport function detectCycles(tasks: Task[]): { hasCycle: boolean; cyclePath?: string[] } {\n const graph = buildAdjacencyList(tasks);\n const visiting = new Set<string>();\n const visited = new Set<string>();\n const path: string[] = [];\n\n function dfs(taskId: string): boolean {\n if (visiting.has(taskId)) {\n return true;\n }\n if (visited.has(taskId)) {\n return false;\n }\n\n visiting.add(taskId);\n path.push(taskId);\n\n const successors = graph.get(taskId) || [];\n for (const successor of successors) {\n if (dfs(successor)) {\n return true;\n }\n }\n\n visiting.delete(taskId);\n path.pop();\n visited.add(taskId);\n return false;\n }\n\n for (const task of tasks) {\n if (dfs(task.id)) {\n return { hasCycle: true, cyclePath: [...path] };\n }\n }\n\n return { hasCycle: false };\n}\n\n/**\n * Validate all dependencies in the task list\n */\nexport function validateDependencies(tasks: Task[]): ValidationResult {\n const errors: DependencyError[] = [];\n const taskIds = new Set(tasks.map(t => t.id));\n\n // Check for missing predecessor references\n for (const task of tasks) {\n if (task.dependencies) {\n for (const dep of task.dependencies) {\n if (!taskIds.has(dep.taskId)) {\n errors.push({\n type: 'missing-task',\n taskId: task.id,\n message: `Dependency references non-existent task: ${dep.taskId}`,\n relatedTaskIds: [dep.taskId],\n });\n }\n }\n }\n }\n\n // Check for invalid hierarchy links (ancestor <-> descendant)\n for (const task of tasks) {\n if (!task.dependencies) continue;\n\n for (const dep of task.dependencies) {\n if (!taskIds.has(dep.taskId)) {\n continue;\n }\n\n if (areTasksHierarchicallyRelated(task.id, dep.taskId, tasks)) {\n errors.push({\n type: 'constraint',\n taskId: task.id,\n message: `Dependencies between parent and child tasks are not allowed: ${dep.taskId} -> ${task.id}`,\n relatedTaskIds: [dep.taskId, task.id],\n });\n }\n }\n }\n\n // Check for cycles\n const cycleResult = detectCycles(tasks);\n if (cycleResult.hasCycle && cycleResult.cyclePath) {\n errors.push({\n type: 'cycle',\n taskId: cycleResult.cyclePath[0],\n message: 'Circular dependency detected',\n relatedTaskIds: cycleResult.cyclePath,\n });\n }\n\n return {\n isValid: errors.length === 0,\n errors,\n };\n}\n","/**\n * UI adapter: converts pixel coordinates to date ranges for drag interactions.\n * @module adapters/scheduling\n *\n * These functions bridge the chart's pixel-space (left, width, dayWidth)\n * with the scheduling domain's date-space. They depend on core scheduling\n * primitives but are NOT part of the domain core themselves.\n */\n\nimport type { Task } from '../../core/scheduling/types';\nimport {\n moveTaskRange,\n buildTaskRangeFromStart,\n buildTaskRangeFromEnd,\n} from '../../core/scheduling/commands';\nimport {\n alignToWorkingDay,\n getBusinessDaysCount,\n} from '../../core/scheduling/dateMath';\nimport { clampTaskRangeForIncomingFS } from '../../core/scheduling/commands';\n\n/**\n * Convert pixel coordinates to a date range, applying business-day alignment\n * when businessDays mode is active. This is the pure scheduling core of\n * drag-to-date conversion.\n *\n * Extracted from useTaskDrag.ts resolveDraggedRange.\n */\nexport function resolveDateRangeFromPixels(\n mode: 'move' | 'resize-left' | 'resize-right',\n left: number,\n width: number,\n monthStart: Date,\n dayWidth: number,\n task: Task,\n businessDays?: boolean,\n weekendPredicate?: (date: Date) => boolean\n): { start: Date; end: Date } {\n const dayOffset = Math.round(left / dayWidth);\n const rawStartDate = new Date(Date.UTC(\n monthStart.getUTCFullYear(),\n monthStart.getUTCMonth(),\n monthStart.getUTCDate() + dayOffset\n ));\n const rawEndOffset = dayOffset + Math.round(width / dayWidth) - 1;\n const rawEndDate = new Date(Date.UTC(\n monthStart.getUTCFullYear(),\n monthStart.getUTCMonth(),\n monthStart.getUTCDate() + rawEndOffset\n ));\n\n if (!(businessDays && weekendPredicate)) {\n return { start: rawStartDate, end: rawEndDate };\n }\n\n if (mode === 'move') {\n const originalStart = new Date(task.startDate as string);\n const snapDirection = rawStartDate.getTime() >= originalStart.getTime() ? 1 : -1;\n return moveTaskRange(\n task.startDate,\n task.endDate,\n rawStartDate,\n true,\n weekendPredicate,\n snapDirection\n );\n }\n\n if (mode === 'resize-right') {\n const fixedStart = new Date(task.startDate as string);\n const originalEnd = new Date(task.endDate as string);\n const snapDirection: 1 | -1 = rawEndDate.getTime() >= originalEnd.getTime() ? 1 : -1;\n const alignedEnd = alignToWorkingDay(rawEndDate, snapDirection, weekendPredicate);\n const duration = Math.max(1, getBusinessDaysCount(fixedStart, alignedEnd, weekendPredicate));\n return buildTaskRangeFromStart(fixedStart, duration, true, weekendPredicate);\n }\n\n const fixedEnd = new Date(task.endDate as string);\n const originalStart = new Date(task.startDate as string);\n const snapDirection: 1 | -1 = rawStartDate.getTime() >= originalStart.getTime() ? 1 : -1;\n const alignedStart = alignToWorkingDay(rawStartDate, snapDirection, weekendPredicate);\n const duration = Math.max(1, getBusinessDaysCount(alignedStart, fixedEnd, weekendPredicate));\n return buildTaskRangeFromEnd(fixedEnd, duration, true, weekendPredicate);\n}\n\n/**\n * Clamp a proposed date range based on incoming FS dependencies.\n * For resize-right mode, returns range unchanged (only start is clamped).\n *\n * Extracted from useTaskDrag.ts clampDraggedRangeForIncomingFS.\n */\nexport function clampDateRangeForIncomingFS(\n task: Task,\n range: { start: Date; end: Date },\n allTasks: Task[],\n mode: 'move' | 'resize-left' | 'resize-right',\n businessDays?: boolean,\n weekendPredicate?: (date: Date) => boolean\n): { start: Date; end: Date } {\n if (mode === 'resize-right') {\n return range;\n }\n\n return clampTaskRangeForIncomingFS(\n task,\n range.start,\n range.end,\n allTasks,\n businessDays,\n weekendPredicate\n );\n}\n"],"mappings":"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","names":["DAY_MS","DAY_MS","originalStart","snapDirection","duration"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/core/scheduling/index.ts","../../../src/core/scheduling/dateMath.ts","../../../src/core/scheduling/dependencies.ts","../../../src/core/scheduling/hierarchy.ts","../../../src/core/scheduling/commands.ts","../../../src/core/scheduling/cascade.ts","../../../src/core/scheduling/execute.ts","../../../src/core/scheduling/validation.ts"],"sourcesContent":["/**\n * Core scheduling module — runtime-agnostic scheduling logic.\n * Zero React/DOM/date-fns dependencies.\n */\nexport * from './types';\nexport * from './dateMath';\nexport * from './dependencies';\nexport * from './cascade';\nexport * from './commands';\nexport * from './execute';\nexport * from './validation';\nexport * from './hierarchy';\n","/**\n * Pure date math utilities for the core scheduling module.\n * Zero React/DOM/date-fns dependencies.\n *\n * Functions moved from:\n * - dependencyUtils.ts: normalizeUTCDate, parseDateOnly, getBusinessDayOffset, shiftBusinessDayOffset, DAY_MS\n * - dateUtils.ts: getBusinessDaysCount, addBusinessDays, subtractBusinessDays\n */\n\nexport const DAY_MS = 24 * 60 * 60 * 1000;\n\n/**\n * Normalize a Date to UTC midnight (hours/minutes/seconds zeroed).\n */\nexport function normalizeUTCDate(date: Date): Date {\n return new Date(Date.UTC(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()));\n}\n\n/**\n * Parse a date string or Date object to a UTC midnight Date.\n * Handles ISO strings like \"2025-01-15\" by appending T00:00:00.000Z.\n */\nexport function parseDateOnly(date: string | Date): Date {\n const parsed = typeof date === 'string'\n ? new Date(`${date.split('T')[0]}T00:00:00.000Z`)\n : normalizeUTCDate(date);\n return normalizeUTCDate(parsed);\n}\n\n/**\n * Compute the business-day offset between two dates.\n * Steps through each calendar day, counting only non-weekend days.\n * Returns a positive number if toDate > fromDate, negative if toDate < fromDate.\n */\nexport function getBusinessDayOffset(\n fromDate: Date,\n toDate: Date,\n weekendPredicate: (date: Date) => boolean\n): number {\n const from = normalizeUTCDate(fromDate);\n const to = normalizeUTCDate(toDate);\n\n if (from.getTime() === to.getTime()) {\n return 0;\n }\n\n const step = to.getTime() > from.getTime() ? 1 : -1;\n const current = new Date(from);\n let offset = 0;\n\n while (current.getTime() !== to.getTime()) {\n current.setUTCDate(current.getUTCDate() + step);\n if (!weekendPredicate(current)) {\n offset += step;\n }\n }\n\n return offset;\n}\n\n/**\n * Shift a date by a business-day offset, skipping weekends.\n */\nexport function shiftBusinessDayOffset(\n date: Date,\n offset: number,\n weekendPredicate: (date: Date) => boolean\n): Date {\n const current = normalizeUTCDate(date);\n\n if (offset === 0) {\n return current;\n }\n\n const step = offset > 0 ? 1 : -1;\n let remaining = Math.abs(offset);\n\n while (remaining > 0) {\n current.setUTCDate(current.getUTCDate() + step);\n if (!weekendPredicate(current)) {\n remaining--;\n }\n }\n\n return current;\n}\n\n/**\n * Count business days between two dates (inclusive), excluding weekends.\n * Returns minimum 1.\n */\nexport function getBusinessDaysCount(\n startDate: string | Date,\n endDate: string | Date,\n weekendPredicate: (date: Date) => boolean\n): number {\n const start = typeof startDate === 'string'\n ? new Date(`${startDate.split('T')[0]}T00:00:00.000Z`)\n : normalizeUTCDate(startDate);\n const end = typeof endDate === 'string'\n ? new Date(`${endDate.split('T')[0]}T00:00:00.000Z`)\n : normalizeUTCDate(endDate);\n\n let count = 0;\n const current = new Date(start);\n\n while (current.getTime() <= end.getTime()) {\n if (!weekendPredicate(current)) {\n count++;\n }\n current.setUTCDate(current.getUTCDate() + 1);\n }\n\n return Math.max(1, count);\n}\n\n/**\n * Calculate end date by adding N business days to start date.\n * Returns a Date object.\n */\nexport function addBusinessDays(\n startDate: string | Date,\n businessDays: number,\n weekendPredicate: (date: Date) => boolean\n): Date {\n const start = typeof startDate === 'string'\n ? new Date(`${startDate.split('T')[0]}T00:00:00.000Z`)\n : normalizeUTCDate(startDate);\n const current = new Date(start);\n let targetDays = Math.max(1, businessDays);\n let businessDaysCounted = 0;\n\n while (businessDaysCounted < targetDays) {\n if (!weekendPredicate(current)) {\n businessDaysCounted++;\n }\n if (businessDaysCounted < targetDays) {\n current.setUTCDate(current.getUTCDate() + 1);\n }\n }\n\n return current;\n}\n\n/**\n * Calculate start date by subtracting N business days from end date.\n * Returns a Date object.\n */\nexport function subtractBusinessDays(\n endDate: string | Date,\n businessDays: number,\n weekendPredicate: (date: Date) => boolean\n): Date {\n const end = typeof endDate === 'string'\n ? new Date(`${endDate.split('T')[0]}T00:00:00.000Z`)\n : normalizeUTCDate(endDate);\n const current = new Date(end);\n let targetDays = Math.max(1, businessDays);\n let businessDaysCounted = 0;\n\n while (businessDaysCounted < targetDays) {\n if (!weekendPredicate(current)) {\n businessDaysCounted++;\n }\n if (businessDaysCounted < targetDays) {\n current.setUTCDate(current.getUTCDate() - 1);\n }\n }\n\n return current;\n}\n\n/**\n * Snap a date to the nearest working day in the given direction.\n */\nexport function alignToWorkingDay(\n date: Date,\n direction: 1 | -1,\n weekendPredicate: (date: Date) => boolean\n): Date {\n const current = normalizeUTCDate(date);\n\n while (weekendPredicate(current)) {\n current.setUTCDate(current.getUTCDate() + direction);\n }\n\n return current;\n}\n\n/**\n * Get task duration in days (inclusive).\n * If businessDays mode, counts business days using weekendPredicate.\n * Otherwise, counts calendar days.\n */\nexport function getTaskDuration(\n startDate: string | Date,\n endDate: string | Date,\n businessDays: boolean = false,\n weekendPredicate?: (date: Date) => boolean\n): number {\n const start = parseDateOnly(startDate);\n const end = parseDateOnly(endDate);\n\n if (businessDays && weekendPredicate) {\n return getBusinessDaysCount(start, end, weekendPredicate);\n }\n\n return Math.max(1, Math.round((end.getTime() - start.getTime()) / DAY_MS) + 1);\n}\n","/**\n * Dependency calculation functions.\n * Moved from dependencyUtils.ts — verbatim implementations.\n * Zero React/DOM/date-fns imports.\n */\n\nimport type { LinkType, TaskDependency } from './types';\nimport {\n getBusinessDayOffset,\n shiftBusinessDayOffset,\n DAY_MS,\n getTaskDuration,\n} from './dateMath';\n\n/**\n * Get lag value from dependency, defaulting to 0.\n */\nexport function getDependencyLag(dep: Pick<TaskDependency, 'lag'>): number {\n return Number.isFinite(dep.lag) ? dep.lag : 0;\n}\n\n/**\n * Normalize lag for FS links — clamp to >= -predecessorDuration.\n */\nexport function normalizeDependencyLag(\n linkType: LinkType,\n lag: number,\n predecessorStart: Date,\n predecessorEnd: Date,\n businessDays: boolean = false,\n weekendPredicate?: (date: Date) => boolean\n): number {\n if (linkType !== 'FS') {\n return lag;\n }\n\n const predecessorDuration = getTaskDuration(\n predecessorStart,\n predecessorEnd,\n businessDays,\n weekendPredicate\n );\n\n return Math.max(-predecessorDuration, lag);\n}\n\n/**\n * Compute lag (in days) from actual predecessor/successor dates.\n * This is the single source of truth for lag semantics.\n *\n * Semantics (lag=0 = natural, gap-free connection):\n * - FS: lag = succStart - predEnd - 1 (adjacent days = 0)\n * - SS: lag = succStart - predStart\n * - FF: lag = succEnd - predEnd\n * - SF: lag = succEnd - predStart + 1 (symmetric to FS)\n */\nexport function computeLagFromDates(\n linkType: LinkType,\n predStart: Date,\n predEnd: Date,\n succStart: Date,\n succEnd: Date,\n businessDays: boolean = false,\n weekendPredicate?: (date: Date) => boolean\n): number {\n const pS = Date.UTC(predStart.getUTCFullYear(), predStart.getUTCMonth(), predStart.getUTCDate());\n const pE = Date.UTC(predEnd.getUTCFullYear(), predEnd.getUTCMonth(), predEnd.getUTCDate());\n const sS = Date.UTC(succStart.getUTCFullYear(), succStart.getUTCMonth(), succStart.getUTCDate());\n const sE = Date.UTC(succEnd.getUTCFullYear(), succEnd.getUTCMonth(), succEnd.getUTCDate());\n\n // Calendar days (original logic)\n if (!businessDays || !weekendPredicate) {\n switch (linkType) {\n case 'FS':\n return normalizeDependencyLag(\n linkType,\n Math.round((sS - pE) / DAY_MS) - 1,\n predStart,\n predEnd,\n businessDays,\n weekendPredicate\n );\n case 'SS': return Math.round((sS - pS) / DAY_MS);\n case 'FF': return Math.round((sE - pE) / DAY_MS);\n case 'SF': return Math.round((sE - pS) / DAY_MS) + 1;\n }\n }\n\n const anchorDate = linkType === 'SS' || linkType === 'SF' ? predStart : predEnd;\n const targetDate = linkType === 'FS' || linkType === 'SS' ? succStart : succEnd;\n const businessOffset = getBusinessDayOffset(anchorDate, targetDate, weekendPredicate);\n\n switch (linkType) {\n case 'FS':\n return normalizeDependencyLag(\n linkType,\n businessOffset - 1,\n predStart,\n predEnd,\n businessDays,\n weekendPredicate\n );\n case 'SS': return businessOffset;\n case 'FF': return businessOffset;\n case 'SF': return businessOffset + 1;\n }\n}\n\n/**\n * Calculate successor date based on predecessor dates, link type, and lag.\n *\n * Link type semantics:\n * - FS: Successor start = Predecessor end + lag + 1 day (lag=0 -> next day)\n * - SS: Successor start = Predecessor start + lag\n * - FF: Successor end = Predecessor end + lag\n * - SF: Successor end = Predecessor start + lag - 1 day (lag=0 -> day before)\n */\nexport function calculateSuccessorDate(\n predecessorStart: Date,\n predecessorEnd: Date,\n linkType: LinkType,\n lag: number = 0,\n businessDays: boolean = false,\n weekendPredicate?: (date: Date) => boolean\n): Date {\n const normalizedLag = normalizeDependencyLag(\n linkType,\n lag,\n predecessorStart,\n predecessorEnd,\n businessDays,\n weekendPredicate\n );\n\n // Calendar days (original logic)\n if (!businessDays || !weekendPredicate) {\n switch (linkType) {\n case 'FS':\n return new Date(predecessorEnd.getTime() + (normalizedLag + 1) * DAY_MS);\n case 'SS':\n return new Date(predecessorStart.getTime() + normalizedLag * DAY_MS);\n case 'FF':\n return new Date(predecessorEnd.getTime() + normalizedLag * DAY_MS);\n case 'SF':\n return new Date(predecessorStart.getTime() + (normalizedLag - 1) * DAY_MS);\n }\n }\n\n const anchorDate = (linkType === 'FS' || linkType === 'FF') ? predecessorEnd : predecessorStart;\n let offset: number;\n switch (linkType) {\n case 'FS':\n offset = normalizedLag + 1;\n break;\n case 'SS':\n offset = normalizedLag;\n break;\n case 'FF':\n offset = normalizedLag;\n break;\n case 'SF':\n offset = normalizedLag - 1;\n break;\n }\n return shiftBusinessDayOffset(anchorDate, offset, weekendPredicate);\n}\n","/**\n * Hierarchy scheduling functions.\n * Moved from dependencyUtils.ts — verbatim implementations.\n * Zero React/DOM/date-fns imports.\n */\n\nimport type { Task } from './types';\n\n/**\n * Get all child tasks of a parent task.\n * Returns tasks where task.parentId === parentId.\n */\nexport function getChildren(parentId: string, tasks: Task[]): Task[] {\n return tasks.filter(t => (t as any).parentId === parentId);\n}\n\n/**\n * Check if a task is a parent (has children).\n * Returns true if any task has this task as parentId.\n */\nexport function isTaskParent(taskId: string, tasks: Task[]): boolean {\n return tasks.some(t => (t as any).parentId === taskId);\n}\n\n/**\n * Compute parent task dates from children.\n * Returns { startDate, endDate } where:\n * - startDate = min(children.startDate) or own startDate if no children\n * - endDate = max(children.endDate) or own endDate if no children\n */\nexport function computeParentDates(parentId: string, tasks: Task[]): { startDate: Date; endDate: Date } {\n const children = getChildren(parentId, tasks);\n\n if (children.length === 0) {\n const parent = tasks.find(t => t.id === parentId);\n const start = parent ? new Date(parent.startDate) : new Date();\n const end = parent ? new Date(parent.endDate) : new Date();\n return { startDate: start, endDate: end };\n }\n\n const startDates = children.map(c => new Date(c.startDate));\n const endDates = children.map(c => new Date(c.endDate));\n\n const minTime = Math.min(...startDates.map(d => d.getTime()));\n const maxTime = Math.max(...endDates.map(d => d.getTime()));\n\n return {\n startDate: new Date(minTime),\n endDate: new Date(maxTime),\n };\n}\n\n/**\n * Compute parent task progress from children (weighted average by duration).\n * Returns 0 if no children.\n * Progress is rounded to 1 decimal place.\n */\nexport function computeParentProgress(parentId: string, tasks: Task[]): number {\n const children = getChildren(parentId, tasks);\n\n if (children.length === 0) {\n return 0;\n }\n\n const DAY_MS = 24 * 60 * 60 * 1000;\n let totalWeight = 0;\n let weightedSum = 0;\n\n for (const child of children) {\n const start = new Date(child.startDate).getTime();\n const end = new Date(child.endDate).getTime();\n // Inclusive duration: (end - start + 1 day) / DAY_MS\n const duration = (end - start + DAY_MS) / DAY_MS;\n const progress = (child.progress ?? 0);\n\n totalWeight += duration;\n weightedSum += duration * progress;\n }\n\n if (totalWeight === 0) {\n return 0;\n }\n\n // Round to 1 decimal place\n return Math.round((weightedSum / totalWeight) * 10) / 10;\n}\n\n/**\n * Get all descendant tasks of a parent task (transitive closure of children).\n * Returns all tasks where task.parentId is in the hierarchy of the parent.\n */\nexport function getAllDescendants(parentId: string, tasks: Task[]): Task[] {\n const descendants: Task[] = [];\n const visited = new Set<string>();\n\n function collectChildren(taskId: string) {\n if (visited.has(taskId)) return;\n visited.add(taskId);\n\n const children = getChildren(taskId, tasks);\n for (const child of children) {\n descendants.push(child);\n collectChildren(child.id);\n }\n }\n\n collectChildren(parentId);\n return descendants;\n}\n\n/**\n * Get all dependency edges for rendering.\n * Returns array of { predecessorId, successorId, type, lag }\n */\nexport function getAllDependencyEdges(tasks: Task[]): Array<{\n predecessorId: string;\n successorId: string;\n type: 'FS' | 'SS' | 'FF' | 'SF';\n lag: number;\n}> {\n const edges: Array<{ predecessorId: string; successorId: string; type: 'FS' | 'SS' | 'FF' | 'SF'; lag: number }> = [];\n\n for (const task of tasks) {\n if (task.dependencies) {\n for (const dep of task.dependencies) {\n edges.push({\n predecessorId: dep.taskId,\n successorId: task.id,\n type: dep.type,\n lag: dep.lag ?? 0,\n });\n }\n }\n }\n\n return edges;\n}\n\n/**\n * Remove dependencies between two tasks in both directions.\n */\nexport function removeDependenciesBetweenTasks(\n taskId1: string,\n taskId2: string,\n tasks: Task[]\n): Task[] {\n return tasks.map(task => {\n if (task.id === taskId1 || task.id === taskId2) {\n if (!task.dependencies) return task;\n const otherTaskId = task.id === taskId1 ? taskId2 : taskId1;\n const filteredDependencies = task.dependencies.filter(dep => dep.taskId !== otherTaskId);\n if (filteredDependencies.length === task.dependencies.length) {\n return task;\n }\n return {\n ...task,\n dependencies: filteredDependencies.length > 0 ? filteredDependencies : undefined,\n };\n }\n return task;\n });\n}\n\n/**\n * Find the parent ID of a task.\n */\nexport function findParentId(taskId: string, tasks: Task[]): string | undefined {\n const task = tasks.find(t => t.id === taskId);\n return task?.parentId;\n}\n\n/**\n * Returns true when ancestorId is an ancestor of taskId in the current hierarchy.\n */\nexport function isAncestorTask(ancestorId: string, taskId: string, tasks: Task[]): boolean {\n const taskById = new Map(tasks.map(task => [task.id, task]));\n const visited = new Set<string>();\n let current = taskById.get(taskId);\n\n while (current?.parentId) {\n if (current.parentId === ancestorId) {\n return true;\n }\n\n if (visited.has(current.parentId)) {\n return false;\n }\n\n visited.add(current.parentId);\n current = taskById.get(current.parentId);\n }\n\n return false;\n}\n\n/**\n * Returns true when tasks are in the same ancestry chain.\n */\nexport function areTasksHierarchicallyRelated(taskId1: string, taskId2: string, tasks: Task[]): boolean {\n if (taskId1 === taskId2) {\n return true;\n }\n\n return isAncestorTask(taskId1, taskId2, tasks) || isAncestorTask(taskId2, taskId1, tasks);\n}\n","/**\n * High-level schedule command functions.\n * Moved from dependencyUtils.ts — verbatim implementations.\n * Zero React/DOM/date-fns imports.\n */\n\nimport type { Task } from './types';\nimport {\n normalizeUTCDate,\n parseDateOnly,\n addBusinessDays,\n subtractBusinessDays,\n alignToWorkingDay,\n getTaskDuration,\n getBusinessDaysCount,\n} from './dateMath';\nimport {\n calculateSuccessorDate,\n getDependencyLag,\n normalizeDependencyLag,\n computeLagFromDates,\n} from './dependencies';\n\n// Re-export for backward compat — these live in dateMath now\nexport { alignToWorkingDay, getTaskDuration };\n\n/**\n * Build a task range (start/end dates) from a start date and duration.\n */\nexport function buildTaskRangeFromStart(\n startDate: Date,\n duration: number,\n businessDays: boolean = false,\n weekendPredicate?: (date: Date) => boolean,\n snapDirection: 1 | -1 = 1\n): { start: Date; end: Date } {\n const normalizedStart = businessDays && weekendPredicate\n ? alignToWorkingDay(startDate, snapDirection, weekendPredicate)\n : normalizeUTCDate(startDate);\n\n if (businessDays && weekendPredicate) {\n return {\n start: normalizedStart,\n end: parseDateOnly(addBusinessDays(normalizedStart, duration, weekendPredicate)),\n };\n }\n\n const DAY_MS = 24 * 60 * 60 * 1000;\n return {\n start: normalizedStart,\n end: new Date(normalizedStart.getTime() + (Math.max(1, duration) - 1) * DAY_MS),\n };\n}\n\n/**\n * Build a task range (start/end dates) from an end date and duration.\n */\nexport function buildTaskRangeFromEnd(\n endDate: Date,\n duration: number,\n businessDays: boolean = false,\n weekendPredicate?: (date: Date) => boolean,\n snapDirection: 1 | -1 = -1\n): { start: Date; end: Date } {\n const normalizedEnd = businessDays && weekendPredicate\n ? alignToWorkingDay(endDate, snapDirection, weekendPredicate)\n : normalizeUTCDate(endDate);\n\n if (businessDays && weekendPredicate) {\n return {\n start: parseDateOnly(subtractBusinessDays(normalizedEnd, duration, weekendPredicate)),\n end: normalizedEnd,\n };\n }\n\n const DAY_MS = 24 * 60 * 60 * 1000;\n return {\n start: new Date(normalizedEnd.getTime() - (Math.max(1, duration) - 1) * DAY_MS),\n end: normalizedEnd,\n };\n}\n\n/**\n * Move a task range to a new start date, preserving duration.\n */\nexport function moveTaskRange(\n originalStart: string | Date,\n originalEnd: string | Date,\n proposedStart: Date,\n businessDays: boolean = false,\n weekendPredicate?: (date: Date) => boolean,\n snapDirection: 1 | -1 = 1\n): { start: Date; end: Date } {\n return buildTaskRangeFromStart(\n proposedStart,\n getTaskDuration(originalStart, originalEnd, businessDays, weekendPredicate),\n businessDays,\n weekendPredicate,\n snapDirection\n );\n}\n\n/**\n * Clamp task range start date based on incoming FS dependencies.\n */\nexport function clampTaskRangeForIncomingFS(\n task: Pick<Task, 'dependencies'>,\n proposedStart: Date,\n proposedEnd: Date,\n allTasks: Task[],\n businessDays: boolean = false,\n weekendPredicate?: (date: Date) => boolean\n): { start: Date; end: Date } {\n if (!task.dependencies?.length) {\n return { start: proposedStart, end: proposedEnd };\n }\n\n let minAllowedStart: Date | null = null;\n\n for (const dep of task.dependencies) {\n if (dep.type !== 'FS') {\n continue;\n }\n\n const predecessor = allTasks.find(candidate => candidate.id === dep.taskId);\n if (!predecessor) {\n continue;\n }\n\n const predecessorStart = parseDateOnly(predecessor.startDate);\n const predecessorEnd = parseDateOnly(predecessor.endDate);\n const predecessorDuration = getTaskDuration(\n predecessorStart,\n predecessorEnd,\n businessDays,\n weekendPredicate\n );\n const candidateMinStart = calculateSuccessorDate(\n predecessorStart,\n predecessorEnd,\n 'FS',\n -predecessorDuration,\n businessDays,\n weekendPredicate\n );\n\n if (!minAllowedStart || candidateMinStart.getTime() > minAllowedStart.getTime()) {\n minAllowedStart = candidateMinStart;\n }\n }\n\n if (!minAllowedStart || proposedStart.getTime() >= minAllowedStart.getTime()) {\n return { start: proposedStart, end: proposedEnd };\n }\n\n return buildTaskRangeFromStart(\n minAllowedStart,\n getTaskDuration(proposedStart, proposedEnd, businessDays, weekendPredicate),\n businessDays,\n weekendPredicate\n );\n}\n\n/**\n * Recalculate incoming dependency lags after a task's dates change.\n */\nexport function recalculateIncomingLags(\n task: Task,\n newStartDate: Date,\n newEndDate: Date,\n allTasks: Task[],\n businessDays: boolean = false,\n weekendPredicate?: (date: Date) => boolean\n): NonNullable<Task['dependencies']> {\n if (!task.dependencies) return [];\n return task.dependencies.map(dep => {\n const predecessor = allTasks.find(candidate => candidate.id === dep.taskId);\n if (!predecessor) {\n return { ...dep, lag: getDependencyLag(dep) };\n }\n\n const predecessorStart = new Date(predecessor.startDate as string);\n const predecessorEnd = new Date(predecessor.endDate as string);\n const nextLag = computeLagFromDates(\n dep.type,\n predecessorStart,\n predecessorEnd,\n newStartDate,\n newEndDate,\n businessDays,\n weekendPredicate\n );\n\n return { ...dep, lag: nextLag };\n });\n}\n\n","/**\n * Cascade engine functions.\n * Moved from dependencyUtils.ts — verbatim implementations.\n * Zero React/DOM/date-fns imports.\n */\n\nimport type { Task, LinkType } from './types';\nimport {\n normalizeUTCDate,\n getTaskDuration,\n alignToWorkingDay,\n} from './dateMath';\nimport {\n calculateSuccessorDate,\n getDependencyLag,\n} from './dependencies';\nimport {\n getChildren,\n isTaskParent,\n computeParentDates,\n} from './hierarchy';\nimport {\n buildTaskRangeFromStart,\n buildTaskRangeFromEnd,\n moveTaskRange,\n} from './commands';\n\n/**\n * Get successor tasks of a dragged task using BFS, filtered by link type(s).\n */\nexport function getSuccessorChain(\n draggedTaskId: string,\n allTasks: Task[],\n linkTypes: LinkType[] = ['FS']\n): Task[] {\n const successorMap = new Map<string, string[]>();\n for (const task of allTasks) {\n successorMap.set(task.id, []);\n }\n for (const task of allTasks) {\n if (!task.dependencies) continue;\n for (const dep of task.dependencies) {\n if (linkTypes.includes(dep.type)) {\n const list = successorMap.get(dep.taskId) ?? [];\n list.push(task.id);\n successorMap.set(dep.taskId, list);\n }\n }\n }\n\n const taskById = new Map(allTasks.map(t => [t.id, t]));\n const visited = new Set<string>();\n const queue: string[] = [draggedTaskId];\n const chain: Task[] = [];\n visited.add(draggedTaskId);\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n const successors = successorMap.get(current) ?? [];\n for (const sid of successors) {\n if (!visited.has(sid)) {\n visited.add(sid);\n const t = taskById.get(sid);\n if (t) {\n chain.push(t);\n queue.push(sid);\n }\n }\n }\n }\n\n return chain;\n}\n\n/**\n * Cascade successors by actual link constraints (BFS, constraint-based).\n */\nexport function cascadeByLinks(\n movedTaskId: string,\n newStart: Date,\n newEnd: Date,\n allTasks: Task[],\n skipChildCascade: boolean = false\n): Task[] {\n const taskById = new Map(allTasks.map(t => [t.id, t]));\n\n const updatedDates = new Map<string, { start: Date; end: Date }>();\n updatedDates.set(movedTaskId, { start: newStart, end: newEnd });\n\n const result: Task[] = [];\n const queue: string[] = [movedTaskId];\n const visited = new Set<string>([movedTaskId]);\n\n while (queue.length > 0) {\n const currentId = queue.shift()!;\n const { start: predStart, end: predEnd } = updatedDates.get(currentId)!;\n\n if (!skipChildCascade) {\n const children = getChildren(currentId, allTasks);\n for (const child of children) {\n if (visited.has(child.id) || child.locked) continue;\n\n const origStart = new Date(child.startDate as string);\n const origEnd = new Date(child.endDate as string);\n const durationMs = origEnd.getTime() - origStart.getTime();\n\n const parentOrig = taskById.get(currentId)!;\n const parentOrigStart = new Date(parentOrig.startDate as string);\n const parentOrigEnd = new Date(parentOrig.endDate as string);\n\n const parentStartDelta = predStart.getTime() - parentOrigStart.getTime();\n const parentEndDelta = predEnd.getTime() - parentOrigEnd.getTime();\n\n const newChildStart = new Date(origStart.getTime() + parentStartDelta);\n const newChildEnd = new Date(origEnd.getTime() + parentEndDelta);\n\n visited.add(child.id);\n updatedDates.set(child.id, { start: newChildStart, end: newChildEnd });\n result.push({\n ...child,\n startDate: newChildStart.toISOString().split('T')[0],\n endDate: newChildEnd.toISOString().split('T')[0],\n });\n queue.push(child.id);\n }\n }\n\n for (const task of allTasks) {\n if (visited.has(task.id) || !task.dependencies || task.locked) continue;\n\n for (const dep of task.dependencies) {\n if (dep.taskId !== currentId) continue;\n\n const orig = taskById.get(task.id)!;\n const origStart = new Date(orig.startDate as string);\n const origEnd = new Date(orig.endDate as string);\n const duration = getTaskDuration(origStart, origEnd);\n const constraintDate = calculateSuccessorDate(predStart, predEnd, dep.type, getDependencyLag(dep));\n\n let newSuccStart: Date;\n let newSuccEnd: Date;\n\n if (dep.type === 'FS' || dep.type === 'SS') {\n ({ start: newSuccStart, end: newSuccEnd } = buildTaskRangeFromStart(constraintDate, duration));\n } else {\n ({ start: newSuccStart, end: newSuccEnd } = buildTaskRangeFromEnd(constraintDate, duration));\n }\n\n visited.add(task.id);\n updatedDates.set(task.id, { start: newSuccStart, end: newSuccEnd });\n result.push({\n ...task,\n startDate: newSuccStart.toISOString().split('T')[0],\n endDate: newSuccEnd.toISOString().split('T')[0],\n });\n queue.push(task.id);\n break;\n }\n }\n }\n\n return result;\n}\n\n/**\n * Get transitive closure of successors for cascading.\n */\nexport function getTransitiveCascadeChain(\n changedTaskId: string,\n allTasks: Task[],\n firstLevelLinkTypes: LinkType[]\n): Task[] {\n const allTypesSuccessorMap = new Map<string, Task[]>();\n for (const task of allTasks) {\n allTypesSuccessorMap.set(task.id, []);\n }\n for (const task of allTasks) {\n if (!task.dependencies) continue;\n for (const dep of task.dependencies) {\n const list = allTypesSuccessorMap.get(dep.taskId) ?? [];\n list.push(task);\n allTypesSuccessorMap.set(dep.taskId, list);\n }\n }\n\n const directChildren = getChildren(changedTaskId, allTasks);\n const directSuccessors = getSuccessorChain(changedTaskId, allTasks, firstLevelLinkTypes);\n const initialChain = [...directChildren, ...directSuccessors].filter((task, index, arr) =>\n arr.findIndex(candidate => candidate.id === task.id) === index\n );\n\n const chain = [...initialChain];\n const visited = new Set<string>([changedTaskId, ...initialChain.map(t => t.id)]);\n const queue = [...initialChain];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n\n const children = getChildren(current.id, allTasks);\n for (const child of children) {\n if (!visited.has(child.id)) {\n visited.add(child.id);\n chain.push(child);\n queue.push(child);\n }\n }\n\n const successors = allTypesSuccessorMap.get(current.id) ?? [];\n for (const successor of successors) {\n if (!visited.has(successor.id)) {\n visited.add(successor.id);\n chain.push(successor);\n queue.push(successor);\n }\n }\n }\n\n return chain;\n}\n\n/**\n * Arrival mode for universal cascade BFS entries.\n */\ntype ArrivalMode = 'direct' | 'child-delta' | 'parent-recalc' | 'dependency';\n\n/**\n * Universal cascade engine that propagates a moved task's new position through\n * the entire dependency+hierarchy graph using BFS with change detection.\n */\nexport function universalCascade(\n movedTask: Task,\n newStart: Date,\n newEnd: Date,\n allTasks: Task[],\n businessDays: boolean = false,\n weekendPredicate?: (date: Date) => boolean\n): Task[] {\n const taskById = new Map(allTasks.map(t => [t.id, t]));\n\n const updatedDates = new Map<string, { start: Date; end: Date }>();\n updatedDates.set(movedTask.id, { start: newStart, end: newEnd });\n\n const resultMap = new Map<string, Task>();\n resultMap.set(movedTask.id, {\n ...movedTask,\n startDate: newStart.toISOString().split('T')[0],\n endDate: newEnd.toISOString().split('T')[0],\n });\n\n const queue: Array<[string, ArrivalMode]> = [[movedTask.id, 'direct']];\n\n const childShifted = new Set<string>();\n\n let iterations = 0;\n const MAX_ITERATIONS = allTasks.length * 3;\n\n while (queue.length > 0 && iterations < MAX_ITERATIONS) {\n iterations++;\n const [currentId, arrivalMode] = queue.shift()!;\n const { start: currStart, end: currEnd } = updatedDates.get(currentId)!;\n const currentOriginal = taskById.get(currentId)!;\n\n // RULE 1: Hierarchy children follow their parent\n if (arrivalMode !== 'parent-recalc') {\n const children = getChildren(currentId, allTasks);\n for (const child of children) {\n if (childShifted.has(child.id) || child.locked) continue;\n\n const parentOrigStart = new Date(currentOriginal.startDate as string);\n const parentOrigEnd = new Date(currentOriginal.endDate as string);\n\n const childOrigStart = new Date(child.startDate as string);\n const childOrigEnd = new Date(child.endDate as string);\n\n const startDeltaMs = currStart.getTime() - parentOrigStart.getTime();\n const endDeltaMs = currEnd.getTime() - parentOrigEnd.getTime();\n\n let childNewStart: Date;\n let childNewEnd: Date;\n\n if (businessDays && weekendPredicate) {\n const proposedStart = new Date(childOrigStart.getTime() + startDeltaMs);\n const snapDirection: 1 | -1 = currStart.getTime() >= parentOrigStart.getTime() ? 1 : -1;\n const movedRange = moveTaskRange(\n child.startDate,\n child.endDate,\n proposedStart,\n true,\n weekendPredicate,\n snapDirection\n );\n childNewStart = movedRange.start;\n childNewEnd = movedRange.end;\n } else {\n childNewStart = new Date(childOrigStart.getTime() + startDeltaMs);\n childNewEnd = new Date(childOrigEnd.getTime() + endDeltaMs);\n }\n\n const prev = updatedDates.get(child.id);\n if (prev && prev.start.getTime() === childNewStart.getTime() && prev.end.getTime() === childNewEnd.getTime()) {\n continue;\n }\n\n updatedDates.set(child.id, { start: childNewStart, end: childNewEnd });\n childShifted.add(child.id);\n queue.push([child.id, 'child-delta']);\n resultMap.set(child.id, {\n ...child,\n startDate: childNewStart.toISOString().split('T')[0],\n endDate: childNewEnd.toISOString().split('T')[0],\n });\n }\n }\n\n // RULE 2: Parent task is recomputed from its children\n const parentId = (currentOriginal as any).parentId as string | undefined;\n if (parentId) {\n const parent = taskById.get(parentId);\n if (parent && !parent.locked) {\n const siblings = getChildren(parentId, allTasks);\n\n const siblingPositions = siblings.map(sib => {\n if (updatedDates.has(sib.id)) return updatedDates.get(sib.id)!;\n return { start: new Date(sib.startDate as string), end: new Date(sib.endDate as string) };\n });\n\n const minStart = new Date(Math.min(...siblingPositions.map(p => p.start.getTime())));\n const maxEnd = new Date(Math.max(...siblingPositions.map(p => p.end.getTime())));\n\n const prev = updatedDates.get(parentId);\n if (!prev || prev.start.getTime() !== minStart.getTime() || prev.end.getTime() !== maxEnd.getTime()) {\n updatedDates.set(parentId, { start: minStart, end: maxEnd });\n queue.push([parentId, 'parent-recalc']);\n resultMap.set(parentId, {\n ...parent,\n startDate: minStart.toISOString().split('T')[0],\n endDate: maxEnd.toISOString().split('T')[0],\n });\n }\n }\n }\n\n // RULE 3: Dependency successors are repositioned\n for (const task of allTasks) {\n if (task.locked || !task.dependencies) continue;\n\n const dep = task.dependencies.find(d => d.taskId === currentId);\n if (!dep) continue;\n\n const origStart = new Date(task.startDate as string);\n const origEnd = new Date(task.endDate as string);\n const constraintDate = calculateSuccessorDate(\n currStart, currEnd, dep.type, getDependencyLag(dep),\n businessDays, weekendPredicate\n );\n\n let succNewStart: Date;\n let succNewEnd: Date;\n const duration = getTaskDuration(origStart, origEnd, businessDays, weekendPredicate);\n\n if (dep.type === 'FS' || dep.type === 'SS') {\n ({ start: succNewStart, end: succNewEnd } = buildTaskRangeFromStart(\n constraintDate,\n duration,\n businessDays,\n weekendPredicate\n ));\n } else {\n ({ start: succNewStart, end: succNewEnd } = buildTaskRangeFromEnd(\n constraintDate,\n duration,\n businessDays,\n weekendPredicate\n ));\n }\n\n const prev = updatedDates.get(task.id);\n if (prev && prev.start.getTime() === succNewStart.getTime() && prev.end.getTime() === succNewEnd.getTime()) {\n continue;\n }\n\n updatedDates.set(task.id, { start: succNewStart, end: succNewEnd });\n queue.push([task.id, 'dependency']);\n resultMap.set(task.id, {\n ...task,\n startDate: succNewStart.toISOString().split('T')[0],\n endDate: succNewEnd.toISOString().split('T')[0],\n });\n }\n }\n\n return Array.from(resultMap.values());\n}\n\n/**\n * Recalculate all task dates when switching between business/calendar day modes.\n */\nexport function reflowTasksOnModeSwitch(\n sourceTasks: Task[],\n toBusinessDays: boolean,\n weekendPredicate: (date: Date) => boolean\n): Task[] {\n const fromBusinessDays = !toBusinessDays;\n let tasks: Task[] = sourceTasks.map(t => ({ ...t }));\n\n const toISO = (d: Date) => d.toISOString().split('T')[0];\n\n for (const task of tasks) {\n if (isTaskParent(task.id, tasks)) continue;\n\n const start = normalizeUTCDate(new Date(`${task.startDate}T00:00:00.000Z`));\n const duration = getTaskDuration(task.startDate, task.endDate, fromBusinessDays, weekendPredicate);\n\n let range: { start: Date; end: Date };\n if (toBusinessDays) {\n const alignedStart = alignToWorkingDay(start, 1, weekendPredicate);\n range = buildTaskRangeFromStart(alignedStart, duration, true, weekendPredicate);\n } else {\n range = buildTaskRangeFromStart(start, duration, false);\n }\n\n task.startDate = toISO(range.start);\n task.endDate = toISO(range.end);\n }\n\n for (const task of tasks) {\n if (!isTaskParent(task.id, tasks)) continue;\n const { startDate, endDate } = computeParentDates(task.id, tasks);\n task.startDate = toISO(startDate);\n task.endDate = toISO(endDate);\n }\n\n if (toBusinessDays) {\n const rootSeeds = tasks.filter(\n t => !(t as any).parentId && (!t.dependencies || t.dependencies.length === 0)\n );\n\n for (const seed of rootSeeds) {\n const current = tasks.find(t => t.id === seed.id)!;\n const start = new Date(`${current.startDate}T00:00:00.000Z`);\n const end = new Date(`${current.endDate}T00:00:00.000Z`);\n\n const cascaded = universalCascade(current, start, end, tasks, toBusinessDays, weekendPredicate);\n const updates = new Map(cascaded.map((t): [string, Task] => [t.id, t]));\n tasks = tasks.map(t => updates.get(t.id) ?? t);\n }\n }\n\n return tasks;\n}\n","/**\n * Command-level scheduling API.\n * High-level functions that compose low-level scheduling primitives.\n * Zero React/DOM/date-fns imports.\n */\n\nimport type { Task, ScheduleCommandResult, ScheduleCommandOptions } from './types';\nimport { moveTaskRange, recalculateIncomingLags, buildTaskRangeFromEnd, buildTaskRangeFromStart, getTaskDuration } from './commands';\nimport { universalCascade } from './cascade';\nimport { parseDateOnly } from './dateMath';\nimport { calculateSuccessorDate, getDependencyLag } from './dependencies';\nimport { computeParentDates, isTaskParent } from './hierarchy';\n\nfunction toIsoDate(date: Date): string {\n return date.toISOString().split('T')[0];\n}\n\nfunction createChangedResult(snapshot: Task[], nextTasks: Task[]): ScheduleCommandResult {\n const originalById = new Map(snapshot.map(task => [task.id, task]));\n const changedTasks = nextTasks.filter(task => JSON.stringify(originalById.get(task.id)) !== JSON.stringify(task));\n\n return {\n changedTasks,\n changedIds: changedTasks.map(task => task.id),\n };\n}\n\n/**\n * Move a task to a new start date with cascade and lag recalculation.\n * Identical to manual composition: moveTaskRange -> recalculateIncomingLags -> universalCascade.\n */\nexport function moveTaskWithCascade(\n taskId: string,\n newStart: Date,\n snapshot: Task[],\n options?: ScheduleCommandOptions\n): ScheduleCommandResult {\n const task = snapshot.find(t => t.id === taskId);\n if (!task) {\n return { changedTasks: [], changedIds: [] };\n }\n\n const businessDays = options?.businessDays ?? false;\n const weekendPredicate = options?.weekendPredicate;\n\n // Step 1: Calculate new range preserving duration\n const newRange = moveTaskRange(\n task.startDate,\n task.endDate,\n newStart,\n businessDays,\n weekendPredicate\n );\n\n // Step 2: Recalculate incoming dependency lags\n const updatedDependencies = recalculateIncomingLags(\n task,\n newRange.start,\n newRange.end,\n snapshot,\n businessDays,\n weekendPredicate\n );\n\n // Step 3: Create moved task with updated deps\n const movedTask: Task = {\n ...task,\n startDate: newRange.start.toISOString().split('T')[0],\n endDate: newRange.end.toISOString().split('T')[0],\n dependencies: updatedDependencies,\n };\n\n // Step 4: Cascade through dependency graph\n if (options?.skipCascade) {\n return {\n changedTasks: [movedTask],\n changedIds: [movedTask.id],\n };\n }\n\n const cascadeResult = universalCascade(\n movedTask,\n newRange.start,\n newRange.end,\n snapshot,\n businessDays,\n weekendPredicate\n );\n\n // Merge: movedTask + cascade results\n const resultMap = new Map<string, Task>();\n resultMap.set(movedTask.id, movedTask);\n for (const t of cascadeResult) {\n resultMap.set(t.id, t);\n }\n\n const changedTasks = Array.from(resultMap.values());\n return {\n changedTasks,\n changedIds: changedTasks.map(t => t.id),\n };\n}\n\n/**\n * Resize a task by changing its start or end date.\n * anchor='end': new end date, start stays fixed.\n * anchor='start': new start date, end stays fixed.\n */\nexport function resizeTaskWithCascade(\n taskId: string,\n anchor: 'start' | 'end',\n newDate: Date,\n snapshot: Task[],\n options?: ScheduleCommandOptions\n): ScheduleCommandResult {\n const task = snapshot.find(t => t.id === taskId);\n if (!task) {\n return { changedTasks: [], changedIds: [] };\n }\n\n const businessDays = options?.businessDays ?? false;\n const weekendPredicate = options?.weekendPredicate;\n\n const originalStart = parseDateOnly(task.startDate);\n const originalEnd = parseDateOnly(task.endDate);\n let newRange: { start: Date; end: Date };\n\n if (anchor === 'end') {\n // anchor='end': new end date, start stays fixed\n newRange = { start: originalStart, end: newDate };\n } else {\n // anchor='start': new start date, end stays fixed\n newRange = { start: newDate, end: originalEnd };\n }\n\n // Recalculate lags\n const updatedDependencies = recalculateIncomingLags(\n task,\n newRange.start,\n newRange.end,\n snapshot,\n businessDays,\n weekendPredicate\n );\n\n // Create resized task\n const resizedTask: Task = {\n ...task,\n startDate: newRange.start.toISOString().split('T')[0],\n endDate: newRange.end.toISOString().split('T')[0],\n dependencies: updatedDependencies,\n };\n\n if (options?.skipCascade) {\n return {\n changedTasks: [resizedTask],\n changedIds: [resizedTask.id],\n };\n }\n\n // Cascade through dependency graph\n const cascadeResult = universalCascade(\n resizedTask,\n newRange.start,\n newRange.end,\n snapshot,\n businessDays,\n weekendPredicate\n );\n\n const resultMap = new Map<string, Task>();\n resultMap.set(resizedTask.id, resizedTask);\n for (const t of cascadeResult) {\n resultMap.set(t.id, t);\n }\n\n const changedTasks = Array.from(resultMap.values());\n return {\n changedTasks,\n changedIds: changedTasks.map(t => t.id),\n };\n}\n\n/**\n * Recalculate a task's dates based on its dependency constraints.\n * Finds all predecessors and computes the most constrained date.\n */\nexport function recalculateTaskFromDependencies(\n taskId: string,\n snapshot: Task[],\n options?: ScheduleCommandOptions\n): ScheduleCommandResult {\n const task = snapshot.find(t => t.id === taskId);\n if (!task) {\n return { changedTasks: [], changedIds: [] };\n }\n\n const businessDays = options?.businessDays ?? false;\n const weekendPredicate = options?.weekendPredicate;\n\n if (!task.dependencies || task.dependencies.length === 0) {\n // No dependencies — return the task as-is\n return {\n changedTasks: [task],\n changedIds: [task.id],\n };\n }\n\n // Find the most constrained start/end based on all predecessors\n let constrainedStart: Date | null = null;\n let constrainedEnd: Date | null = null;\n\n for (const dep of task.dependencies) {\n const predecessor = snapshot.find(t => t.id === dep.taskId);\n if (!predecessor) continue;\n\n const predStart = parseDateOnly(predecessor.startDate);\n const predEnd = parseDateOnly(predecessor.endDate);\n const constraintDate = calculateSuccessorDate(\n predStart,\n predEnd,\n dep.type,\n getDependencyLag(dep),\n businessDays,\n weekendPredicate\n );\n\n const duration = getTaskDuration(\n parseDateOnly(task.startDate),\n parseDateOnly(task.endDate),\n businessDays,\n weekendPredicate\n );\n\n let range: { start: Date; end: Date };\n if (dep.type === 'FS' || dep.type === 'SS') {\n range = buildTaskRangeFromStart(constraintDate, duration, businessDays, weekendPredicate);\n } else {\n range = buildTaskRangeFromEnd(constraintDate, duration, businessDays, weekendPredicate);\n }\n\n // Take the latest start as the effective constraint\n if (!constrainedStart || range.start.getTime() > constrainedStart.getTime()) {\n constrainedStart = range.start;\n constrainedEnd = range.end;\n }\n }\n\n if (!constrainedStart || !constrainedEnd) {\n return {\n changedTasks: [task],\n changedIds: [task.id],\n };\n }\n\n // Recalculate lags for the new position\n const updatedDependencies = recalculateIncomingLags(\n task,\n constrainedStart,\n constrainedEnd,\n snapshot,\n businessDays,\n weekendPredicate\n );\n\n const recalculatedTask: Task = {\n ...task,\n startDate: constrainedStart.toISOString().split('T')[0],\n endDate: constrainedEnd.toISOString().split('T')[0],\n dependencies: updatedDependencies,\n };\n\n if (options?.skipCascade) {\n return {\n changedTasks: [recalculatedTask],\n changedIds: [recalculatedTask.id],\n };\n }\n\n // Cascade through dependency graph\n const cascadeResult = universalCascade(\n recalculatedTask,\n constrainedStart,\n constrainedEnd,\n snapshot,\n businessDays,\n weekendPredicate\n );\n\n const resultMap = new Map<string, Task>();\n resultMap.set(recalculatedTask.id, recalculatedTask);\n for (const t of cascadeResult) {\n resultMap.set(t.id, t);\n }\n\n const changedTasks = Array.from(resultMap.values());\n return {\n changedTasks,\n changedIds: changedTasks.map(t => t.id),\n };\n}\n\n/**\n * Full project schedule recalculation.\n * Recomputes the project against a continuously updated working snapshot.\n * Returns only tasks whose normalized state changed.\n */\nexport function recalculateProjectSchedule(\n snapshot: Task[],\n options?: ScheduleCommandOptions\n): ScheduleCommandResult {\n const businessDays = options?.businessDays ?? false;\n const weekendPredicate = options?.weekendPredicate;\n const workingMap = new Map(snapshot.map(task => [task.id, { ...task }]));\n const indegree = new Map<string, number>();\n const successorIdsByTask = new Map<string, string[]>();\n\n for (const task of snapshot) {\n indegree.set(task.id, 0);\n successorIdsByTask.set(task.id, []);\n }\n\n for (const task of snapshot) {\n for (const dep of task.dependencies ?? []) {\n if (!workingMap.has(dep.taskId)) {\n continue;\n }\n\n indegree.set(task.id, (indegree.get(task.id) ?? 0) + 1);\n successorIdsByTask.get(dep.taskId)?.push(task.id);\n }\n }\n\n const queue = snapshot\n .filter(task => (indegree.get(task.id) ?? 0) === 0)\n .map(task => task.id);\n\n while (queue.length > 0) {\n const currentId = queue.shift()!;\n\n for (const successorId of successorIdsByTask.get(currentId) ?? []) {\n const nextIndegree = (indegree.get(successorId) ?? 0) - 1;\n indegree.set(successorId, nextIndegree);\n\n if (nextIndegree !== 0) {\n continue;\n }\n\n const currentTask = workingMap.get(successorId);\n if (!currentTask || currentTask.locked || !currentTask.dependencies?.length) {\n queue.push(successorId);\n continue;\n }\n\n const duration = getTaskDuration(\n parseDateOnly(currentTask.startDate),\n parseDateOnly(currentTask.endDate),\n businessDays,\n weekendPredicate\n );\n\n let constrainedRange: { start: Date; end: Date } | null = null;\n\n for (const dep of currentTask.dependencies) {\n const predecessor = workingMap.get(dep.taskId);\n if (!predecessor) {\n continue;\n }\n\n const predecessorStart = parseDateOnly(predecessor.startDate);\n const predecessorEnd = parseDateOnly(predecessor.endDate);\n const constraintDate = calculateSuccessorDate(\n predecessorStart,\n predecessorEnd,\n dep.type,\n getDependencyLag(dep),\n businessDays,\n weekendPredicate\n );\n\n const candidateRange = dep.type === 'FS' || dep.type === 'SS'\n ? buildTaskRangeFromStart(constraintDate, duration, businessDays, weekendPredicate)\n : buildTaskRangeFromEnd(constraintDate, duration, businessDays, weekendPredicate);\n\n if (\n !constrainedRange ||\n candidateRange.start.getTime() > constrainedRange.start.getTime() ||\n (\n candidateRange.start.getTime() === constrainedRange.start.getTime() &&\n candidateRange.end.getTime() > constrainedRange.end.getTime()\n )\n ) {\n constrainedRange = candidateRange;\n }\n }\n\n if (!constrainedRange) {\n queue.push(successorId);\n continue;\n }\n\n workingMap.set(successorId, {\n ...currentTask,\n startDate: toIsoDate(constrainedRange.start),\n endDate: toIsoDate(constrainedRange.end),\n });\n queue.push(successorId);\n }\n }\n\n const parentsByDepth = snapshot\n .filter(task => isTaskParent(task.id, snapshot))\n .map(task => {\n let depth = 0;\n let current = task.parentId ? workingMap.get(task.parentId) : undefined;\n while (current) {\n depth++;\n current = current.parentId ? workingMap.get(current.parentId) : undefined;\n }\n return { taskId: task.id, depth };\n })\n .sort((left, right) => right.depth - left.depth);\n\n const workingTasks = () => Array.from(workingMap.values());\n\n for (const { taskId } of parentsByDepth) {\n const parent = workingMap.get(taskId);\n if (!parent || parent.locked) {\n continue;\n }\n\n const { startDate, endDate } = computeParentDates(taskId, workingTasks());\n workingMap.set(taskId, {\n ...parent,\n startDate: toIsoDate(startDate),\n endDate: toIsoDate(endDate),\n });\n }\n\n return createChangedResult(snapshot, Array.from(workingMap.values()));\n}\n","/**\n * Dependency validation and cycle detection.\n * Moved from dependencyUtils.ts — verbatim implementations.\n * Zero React/DOM/date-fns imports.\n */\n\nimport type { Task, DependencyError, ValidationResult } from './types';\nimport { areTasksHierarchicallyRelated } from './hierarchy';\n\n/**\n * Build adjacency list for dependency graph (task -> successors)\n */\nexport function buildAdjacencyList(tasks: Task[]): Map<string, string[]> {\n const graph = new Map<string, string[]>();\n\n for (const task of tasks) {\n const successors: string[] = [];\n\n // Find all tasks that depend on this task (this task is a predecessor)\n for (const otherTask of tasks) {\n if (otherTask.dependencies) {\n for (const dep of otherTask.dependencies) {\n if (dep.taskId === task.id) {\n successors.push(otherTask.id);\n break;\n }\n }\n }\n }\n\n graph.set(task.id, successors);\n }\n\n return graph;\n}\n\n/**\n * Detect circular dependencies using depth-first search\n */\nexport function detectCycles(tasks: Task[]): { hasCycle: boolean; cyclePath?: string[] } {\n const graph = buildAdjacencyList(tasks);\n const visiting = new Set<string>();\n const visited = new Set<string>();\n const path: string[] = [];\n\n function dfs(taskId: string): boolean {\n if (visiting.has(taskId)) {\n return true;\n }\n if (visited.has(taskId)) {\n return false;\n }\n\n visiting.add(taskId);\n path.push(taskId);\n\n const successors = graph.get(taskId) || [];\n for (const successor of successors) {\n if (dfs(successor)) {\n return true;\n }\n }\n\n visiting.delete(taskId);\n path.pop();\n visited.add(taskId);\n return false;\n }\n\n for (const task of tasks) {\n if (dfs(task.id)) {\n return { hasCycle: true, cyclePath: [...path] };\n }\n }\n\n return { hasCycle: false };\n}\n\n/**\n * Validate all dependencies in the task list\n */\nexport function validateDependencies(tasks: Task[]): ValidationResult {\n const errors: DependencyError[] = [];\n const taskIds = new Set(tasks.map(t => t.id));\n\n // Check for missing predecessor references\n for (const task of tasks) {\n if (task.dependencies) {\n for (const dep of task.dependencies) {\n if (!taskIds.has(dep.taskId)) {\n errors.push({\n type: 'missing-task',\n taskId: task.id,\n message: `Dependency references non-existent task: ${dep.taskId}`,\n relatedTaskIds: [dep.taskId],\n });\n }\n }\n }\n }\n\n // Check for invalid hierarchy links (ancestor <-> descendant)\n for (const task of tasks) {\n if (!task.dependencies) continue;\n\n for (const dep of task.dependencies) {\n if (!taskIds.has(dep.taskId)) {\n continue;\n }\n\n if (areTasksHierarchicallyRelated(task.id, dep.taskId, tasks)) {\n errors.push({\n type: 'constraint',\n taskId: task.id,\n message: `Dependencies between parent and child tasks are not allowed: ${dep.taskId} -> ${task.id}`,\n relatedTaskIds: [dep.taskId, task.id],\n });\n }\n }\n }\n\n // Check for cycles\n const cycleResult = detectCycles(tasks);\n if (cycleResult.hasCycle && cycleResult.cyclePath) {\n errors.push({\n type: 'cycle',\n taskId: cycleResult.cyclePath[0],\n message: 'Circular dependency detected',\n relatedTaskIds: cycleResult.cyclePath,\n });\n }\n\n return {\n isValid: errors.length === 0,\n errors,\n };\n}\n"],"mappings":"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","names":["DAY_MS","DAY_MS"]}
|
|
@@ -1141,64 +1141,6 @@ function validateDependencies(tasks) {
|
|
|
1141
1141
|
errors
|
|
1142
1142
|
};
|
|
1143
1143
|
}
|
|
1144
|
-
|
|
1145
|
-
// src/adapters/scheduling/drag.ts
|
|
1146
|
-
function resolveDateRangeFromPixels(mode, left, width, monthStart, dayWidth, task, businessDays, weekendPredicate) {
|
|
1147
|
-
const dayOffset = Math.round(left / dayWidth);
|
|
1148
|
-
const rawStartDate = new Date(Date.UTC(
|
|
1149
|
-
monthStart.getUTCFullYear(),
|
|
1150
|
-
monthStart.getUTCMonth(),
|
|
1151
|
-
monthStart.getUTCDate() + dayOffset
|
|
1152
|
-
));
|
|
1153
|
-
const rawEndOffset = dayOffset + Math.round(width / dayWidth) - 1;
|
|
1154
|
-
const rawEndDate = new Date(Date.UTC(
|
|
1155
|
-
monthStart.getUTCFullYear(),
|
|
1156
|
-
monthStart.getUTCMonth(),
|
|
1157
|
-
monthStart.getUTCDate() + rawEndOffset
|
|
1158
|
-
));
|
|
1159
|
-
if (!(businessDays && weekendPredicate)) {
|
|
1160
|
-
return { start: rawStartDate, end: rawEndDate };
|
|
1161
|
-
}
|
|
1162
|
-
if (mode === "move") {
|
|
1163
|
-
const originalStart2 = new Date(task.startDate);
|
|
1164
|
-
const snapDirection2 = rawStartDate.getTime() >= originalStart2.getTime() ? 1 : -1;
|
|
1165
|
-
return moveTaskRange(
|
|
1166
|
-
task.startDate,
|
|
1167
|
-
task.endDate,
|
|
1168
|
-
rawStartDate,
|
|
1169
|
-
true,
|
|
1170
|
-
weekendPredicate,
|
|
1171
|
-
snapDirection2
|
|
1172
|
-
);
|
|
1173
|
-
}
|
|
1174
|
-
if (mode === "resize-right") {
|
|
1175
|
-
const fixedStart = new Date(task.startDate);
|
|
1176
|
-
const originalEnd = new Date(task.endDate);
|
|
1177
|
-
const snapDirection2 = rawEndDate.getTime() >= originalEnd.getTime() ? 1 : -1;
|
|
1178
|
-
const alignedEnd = alignToWorkingDay(rawEndDate, snapDirection2, weekendPredicate);
|
|
1179
|
-
const duration2 = Math.max(1, getBusinessDaysCount(fixedStart, alignedEnd, weekendPredicate));
|
|
1180
|
-
return buildTaskRangeFromStart(fixedStart, duration2, true, weekendPredicate);
|
|
1181
|
-
}
|
|
1182
|
-
const fixedEnd = new Date(task.endDate);
|
|
1183
|
-
const originalStart = new Date(task.startDate);
|
|
1184
|
-
const snapDirection = rawStartDate.getTime() >= originalStart.getTime() ? 1 : -1;
|
|
1185
|
-
const alignedStart = alignToWorkingDay(rawStartDate, snapDirection, weekendPredicate);
|
|
1186
|
-
const duration = Math.max(1, getBusinessDaysCount(alignedStart, fixedEnd, weekendPredicate));
|
|
1187
|
-
return buildTaskRangeFromEnd(fixedEnd, duration, true, weekendPredicate);
|
|
1188
|
-
}
|
|
1189
|
-
function clampDateRangeForIncomingFS(task, range, allTasks, mode, businessDays, weekendPredicate) {
|
|
1190
|
-
if (mode === "resize-right") {
|
|
1191
|
-
return range;
|
|
1192
|
-
}
|
|
1193
|
-
return clampTaskRangeForIncomingFS(
|
|
1194
|
-
task,
|
|
1195
|
-
range.start,
|
|
1196
|
-
range.end,
|
|
1197
|
-
allTasks,
|
|
1198
|
-
businessDays,
|
|
1199
|
-
weekendPredicate
|
|
1200
|
-
);
|
|
1201
|
-
}
|
|
1202
1144
|
export {
|
|
1203
1145
|
DAY_MS,
|
|
1204
1146
|
addBusinessDays,
|
|
@@ -1209,7 +1151,6 @@ export {
|
|
|
1209
1151
|
buildTaskRangeFromStart,
|
|
1210
1152
|
calculateSuccessorDate,
|
|
1211
1153
|
cascadeByLinks,
|
|
1212
|
-
clampDateRangeForIncomingFS,
|
|
1213
1154
|
clampTaskRangeForIncomingFS,
|
|
1214
1155
|
computeLagFromDates,
|
|
1215
1156
|
computeParentDates,
|
|
@@ -1238,7 +1179,6 @@ export {
|
|
|
1238
1179
|
reflowTasksOnModeSwitch,
|
|
1239
1180
|
removeDependenciesBetweenTasks,
|
|
1240
1181
|
resizeTaskWithCascade,
|
|
1241
|
-
resolveDateRangeFromPixels,
|
|
1242
1182
|
shiftBusinessDayOffset,
|
|
1243
1183
|
subtractBusinessDays,
|
|
1244
1184
|
universalCascade,
|