gantt-lib 0.131.0 → 0.131.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/scheduling/index.d.mts +1 -1
- package/dist/core/scheduling/index.d.ts +1 -1
- package/dist/core/scheduling/index.js +1 -1
- package/dist/core/scheduling/index.js.map +1 -1
- package/dist/core/scheduling/index.mjs +1 -1
- package/dist/core/scheduling/index.mjs.map +1 -1
- package/dist/{index-CZ_2i1CO.d.mts → index-5SEBp7fs.d.mts} +5 -3
- package/dist/{index-CZ_2i1CO.d.ts → index-5SEBp7fs.d.ts} +5 -3
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/core/scheduling/index.ts","../../../src/core/scheduling/dateMath.ts","../../../src/core/scheduling/dependencies.ts","../../../src/core/scheduling/criticalPath.ts","../../../src/core/scheduling/commands.ts","../../../src/core/scheduling/cascade.ts","../../../src/core/scheduling/hierarchy.ts","../../../src/core/scheduling/execute.ts","../../../src/core/scheduling/modeSwitch.ts","../../../src/core/scheduling/validation.ts","../../../src/core/scheduling/subtreeScaling.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 './criticalPath';\nexport * from './cascade';\nexport * from './modeSwitch';\nexport * from './commands';\nexport * from './execute';\nexport * from './validation';\nexport * from './hierarchy';\nexport * from './subtreeScaling';\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\n// START_MODULE_CONTRACT\n// PURPOSE: Calculate dependency dates and lags using inclusive task dates and explicit milestone semantics.\n// SCOPE: Normalize dependency inputs, calculate successor anchors, and derive lag values from task ranges.\n// DEPENDS: dateMath, scheduling types\n// LINKS: M-SCHEDULING, fn-calculateSuccessorDate, fn-computeLagFromDates\n// ROLE: RUNTIME\n// MAP_MODE: EXPORTS\n// END_MODULE_CONTRACT\n\nimport type { LinkType, TaskDependency, Task } from './types';\nimport {\n getBusinessDayOffset,\n shiftBusinessDayOffset,\n DAY_MS,\n getTaskDuration,\n} from './dateMath';\n\n/**\n * Normalize predecessor dates for scheduling calculations.\n * Milestones have a real zero-duration finish anchor at startDate. The\n * successor type, rather than a fabricated predecessor date, determines\n * whether FS lag=0 lands on the same day (milestone successor) or the next\n * day (regular successor).\n */\nexport function normalizePredecessorDates(\n predecessor: Pick<Task, 'startDate' | 'endDate' | 'type'>,\n parseDateFn: (d: string | Date) => Date\n): { predStart: Date; predEnd: Date } {\n const predStart = parseDateFn(predecessor.startDate);\n const predEnd = predecessor.type === 'milestone'\n ? predStart\n : parseDateFn(predecessor.endDate);\n return { predStart, predEnd };\n}\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 * Return a copy of a task with dependency lag values normalized.\n *\n * FS lag normalization depends on predecessor duration, so this helper\n * intentionally leaves dependencies unchanged.\n */\nexport function normalizeTaskDependencyLags<TTask extends Pick<Task, 'dependencies'>>(task: TTask): TTask {\n return task;\n}\n\n/**\n * Normalize lag for FS links. Regular successors clamp to\n * `-predecessorDuration`; milestone successors use one fewer day because\n * their zero-duration FS anchor is the predecessor finish date itself.\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 successorType?: Task['type']\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 const minimumLag = successorType === 'milestone'\n ? -(Math.max(0, predecessorDuration - 1))\n : -predecessorDuration;\n\n return Math.max(minimumLag, 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 regular-task days = 0)\n * milestone successor uses succStart - predEnd (same-day = 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 successorType?: Task['type']\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) - (successorType === 'milestone' ? 0 : 1),\n predStart,\n predEnd,\n businessDays,\n weekendPredicate,\n successorType\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 - (successorType === 'milestone' ? 0 : 1),\n predStart,\n predEnd,\n businessDays,\n weekendPredicate,\n successorType\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 for regular tasks\n * and Predecessor end + lag for milestone successors\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 successorType?: Task['type']\n): Date {\n const normalizedLag = normalizeDependencyLag(\n linkType,\n lag,\n predecessorStart,\n predecessorEnd,\n businessDays,\n weekendPredicate,\n successorType\n );\n\n // Calendar days (original logic)\n if (!businessDays || !weekendPredicate) {\n switch (linkType) {\n case 'FS':\n return new Date(predecessorEnd.getTime() + (\n normalizedLag + (successorType === 'milestone' ? 0 : 1)\n ) * 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 + (successorType === 'milestone' ? 0 : 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 * Critical path (CPM) calculation over dependency links.\n * Zero React/DOM/date-fns imports.\n *\n * Semantics:\n * - Only leaf tasks (no task references them as parentId) participate in the graph.\n * - All link types are edges — FS, SS, FF, SF — with calendar lags, mirroring\n * calculateSuccessorDate:\n * FS: succStart >= predEnd + lag SS: succStart >= predStart + lag\n * FF: succEnd >= predEnd + lag SF: succEnd >= predStart + lag\n * - A dependency on a parent task (a task that has children) is expanded to its\n * leaf descendants with the same link type and lag. For finish-anchored links\n * (FS/FF) the group is bounded by its latest-finishing leaf; for start-anchored\n * links (SS/SF) by its latest-starting leaf — a conservative approximation of\n * the group's span.\n * - Task weight = business-day duration (getTaskDuration); edge weight = lag in the\n * active scheduling unit.\n * - The scheduled task dates are used as the current starts. The project finish is\n * the latest scheduled leaf finish, so a late short branch can be critical even\n * when a longer branch started earlier.\n * - Task is critical when its total float (late start - scheduled start) is <= 0.\n * A standalone task can therefore be critical when it determines the project\n * finish; dependency membership is not a prerequisite for criticality.\n * - Cycles are skipped by topological ordering (Kahn) — cyclic tasks are not critical.\n */\n\nimport type { ScheduleTask, LinkType } from './types';\nimport { DAY_MS, getBusinessDayOffset, getTaskDuration, parseDateOnly } from './dateMath';\nimport { getDependencyLag } from './dependencies';\n\nexport interface CriticalPathOptions {\n businessDays?: boolean;\n weekendPredicate?: (date: Date) => boolean;\n}\n\ninterface Edge {\n succId: string;\n lag: number;\n type: LinkType;\n}\n\nexport function computeCriticalPath(\n tasks: ScheduleTask[],\n options: CriticalPathOptions = {}\n): Set<string> {\n const { businessDays = false, weekendPredicate } = options;\n\n const taskById = new Map(tasks.map((task) => [task.id, task]));\n\n const childIds = new Set<string>();\n for (const task of tasks) {\n if (task.parentId) childIds.add(task.parentId);\n }\n const leafTasks = tasks.filter((task) => !childIds.has(task.id));\n const leafIds = new Set(leafTasks.map((task) => task.id));\n\n // Map any task id (parent or not) to ALL of its leaf descendants (transitive).\n const leafIdsByAncestor = new Map<string, Set<string>>();\n for (const leaf of leafTasks) {\n let ancestor: string | undefined = leaf.parentId;\n while (ancestor) {\n const set = leafIdsByAncestor.get(ancestor) ?? new Set<string>();\n set.add(leaf.id);\n leafIdsByAncestor.set(ancestor, set);\n ancestor = taskById.get(ancestor)?.parentId;\n }\n }\n\n const durationOf = (task: ScheduleTask): number =>\n getTaskDuration(task.startDate, task.endDate, businessDays, weekendPredicate);\n\n const projectStartDate = leafTasks.reduce((earliest, task) => {\n const taskStart = parseDateOnly(task.startDate);\n return taskStart.getTime() < earliest.getTime() ? taskStart : earliest;\n }, parseDateOnly(leafTasks[0]?.startDate ?? new Date()));\n\n const offsetFromProjectStart = (date: string | Date): number => {\n const targetDate = parseDateOnly(date);\n if (businessDays && weekendPredicate) {\n return getBusinessDayOffset(projectStartDate, targetDate, weekendPredicate);\n }\n return Math.round((targetDate.getTime() - projectStartDate.getTime()) / DAY_MS);\n };\n\n // The current schedule is the forward pass. Do not reset every root task to\n // day zero: its actual start date is what gives it (or removes) total float.\n const scheduledStart = new Map<string, number>();\n for (const leaf of leafTasks) {\n scheduledStart.set(leaf.id, offsetFromProjectStart(leaf.startDate));\n }\n\n // Adjacency over all link types: predecessor -> successors, successor -> predecessors.\n const succByPred = new Map<string, Edge[]>();\n const predBySucc = new Map<string, Array<{ predId: string; lag: number; type: LinkType }>>();\n const seenEdges = new Set<string>();\n\n const addEdge = (predecessorId: string, succId: string, lag: number, type: LinkType) => {\n const edgeKey = `${predecessorId}|${succId}|${type}`;\n if (seenEdges.has(edgeKey)) return;\n seenEdges.add(edgeKey);\n\n const outEdges = succByPred.get(predecessorId) ?? [];\n outEdges.push({ succId, lag, type });\n succByPred.set(predecessorId, outEdges);\n\n const inEdges = predBySucc.get(succId) ?? [];\n inEdges.push({ predId: predecessorId, lag, type });\n predBySucc.set(succId, inEdges);\n };\n\n for (const succ of leafTasks) {\n for (const dep of succ.dependencies ?? []) {\n const lag = getDependencyLag(dep);\n\n // Predecessor is a leaf: direct edge.\n if (leafIds.has(dep.taskId)) {\n addEdge(dep.taskId, succ.id, lag, dep.type);\n continue;\n }\n\n // Predecessor is a parent/group: expand to every leaf descendant.\n // The successor's own leaf (self-loop) is skipped.\n const descendants = leafIdsByAncestor.get(dep.taskId);\n if (!descendants || descendants.size === 0) continue;\n for (const leafId of descendants) {\n if (leafId === succ.id) continue;\n addEdge(leafId, succ.id, lag, dep.type);\n }\n }\n }\n\n // Topological order (Kahn). Vertices trapped in cycles never enter the order\n // (indegree never drops to 0) and are therefore excluded from criticality.\n const indegree = new Map<string, number>();\n for (const leaf of leafTasks) indegree.set(leaf.id, 0);\n for (const edges of succByPred.values()) {\n for (const { succId } of edges) {\n indegree.set(succId, (indegree.get(succId) ?? 0) + 1);\n }\n }\n\n const order: string[] = [];\n const enqueued = new Set<string>();\n const queue = leafTasks\n .filter((leaf) => (indegree.get(leaf.id) ?? 0) === 0)\n .map((leaf) => leaf.id);\n for (const id of queue) enqueued.add(id);\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n order.push(current);\n for (const { succId } of succByPred.get(current) ?? []) {\n const next = (indegree.get(succId) ?? 0) - 1;\n indegree.set(succId, next);\n if (next === 0 && !enqueued.has(succId)) {\n enqueued.add(succId);\n queue.push(succId);\n }\n }\n }\n\n const projectFinish = Math.max(\n 0,\n ...leafTasks.map((leaf) => (scheduledStart.get(leaf.id) ?? 0) + durationOf(leaf))\n );\n\n // Backward pass: late finish / late start.\n const LF = new Map<string, number>();\n const LS = new Map<string, number>();\n for (const leaf of leafTasks) LF.set(leaf.id, projectFinish);\n\n for (let i = order.length - 1; i >= 0; i--) {\n const id = order[i];\n const task = taskById.get(id)!;\n const durPred = durationOf(task);\n const outEdges = succByPred.get(id) ?? [];\n let lf = projectFinish;\n if (outEdges.length > 0) {\n const candidates = outEdges.map(({ succId, lag, type }) => {\n const succLs = LS.get(succId) ?? projectFinish;\n const durSucc = durationOf(taskById.get(succId)!);\n switch (type) {\n case 'FS': return succLs - lag;\n case 'SS': return succLs - lag + durPred;\n case 'FF': return succLs + durSucc - lag;\n case 'SF': return succLs + durSucc - lag + durPred;\n default: return projectFinish;\n }\n });\n lf = Math.min(projectFinish, ...candidates);\n }\n LF.set(id, lf);\n LS.set(id, lf - durPred);\n }\n\n const critical = new Set<string>();\n const ordered = new Set(order);\n for (const leaf of leafTasks) {\n // Vertices trapped in cycles never entered the topological order and are\n // never critical.\n if (!ordered.has(leaf.id)) continue;\n const hasGraphEdge =\n (succByPred.get(leaf.id)?.length ?? 0) > 0 ||\n (predBySucc.get(leaf.id)?.length ?? 0) > 0;\n // A task with no declared dependencies is a legitimate standalone\n // project task and may determine the project finish. If it declares\n // dependencies but none resolved to a valid graph edge (for example a\n // self-reference through its own parent), it is not a schedulable path.\n if (!hasGraphEdge && (leaf.dependencies?.length ?? 0) > 0) continue;\n const es = scheduledStart.get(leaf.id) ?? 0;\n const ls = LS.get(leaf.id) ?? 0;\n if (ls - es <= 0) critical.add(leaf.id);\n }\n\n return critical;\n}\n\n/**\n * Extend criticality from leaf ids upward through the parent chain.\n * A parent is critical when any of its descendants is critical.\n */\nexport function extendCriticalIdsToParents(\n criticalLeafIds: Set<string>,\n tasks: ScheduleTask[]\n): Set<string> {\n const result = new Set(criticalLeafIds);\n const parentByChild = new Map<string, string>();\n for (const task of tasks) {\n if (task.parentId) parentByChild.set(task.id, task.parentId);\n }\n\n const stack = Array.from(criticalLeafIds);\n while (stack.length > 0) {\n const id = stack.pop()!;\n const parentId = parentByChild.get(id);\n if (parentId && !result.has(parentId)) {\n result.add(parentId);\n stack.push(parentId);\n }\n }\n\n return result;\n}\n","/**\n * High-level schedule command functions.\n * Moved from dependencyUtils.ts — verbatim implementations.\n * Zero React/DOM/date-fns imports.\n */\n\n// START_MODULE_CONTRACT\n// PURPOSE: Build task ranges and update dependency lags for interactive scheduling commands.\n// SCOPE: Range construction, incoming FS clamping, and lag recalculation.\n// DEPENDS: dateMath, dependencies, scheduling types\n// LINKS: M-SCHEDULING, fn-clampTaskRangeForIncomingFS, fn-recalculateIncomingLags\n// ROLE: RUNTIME\n// MAP_MODE: EXPORTS\n// END_MODULE_CONTRACT\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 computeLagFromDates,\n normalizePredecessorDates,\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' | 'type'>,\n proposedStart: Date,\n proposedEnd: Date,\n allTasks: Task[],\n businessDays: boolean = false,\n weekendPredicate?: (date: Date) => boolean,\n taskById?: Map<string, Task>\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 = taskById?.get(dep.taskId) ?? allTasks.find(candidate => candidate.id === dep.taskId);\n if (!predecessor) {\n continue;\n }\n\n const { predStart: predecessorStart, predEnd: predecessorEnd } = normalizePredecessorDates(predecessor, parseDateOnly);\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 task.type\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 taskById?: Map<string, Task>\n): NonNullable<Task['dependencies']> {\n if (!task.dependencies) return [];\n return task.dependencies.map(dep => {\n const predecessor = taskById?.get(dep.taskId) ?? allTasks.find(candidate => candidate.id === dep.taskId);\n if (!predecessor) {\n return { ...dep, lag: getDependencyLag(dep) };\n }\n\n const { predStart: predecessorStart, predEnd: predecessorEnd } = normalizePredecessorDates(\n predecessor,\n (d) => new Date(d instanceof Date ? d.getTime() : `${String(d).split('T')[0]}T00:00:00.000Z`)\n );\n const nextLag = computeLagFromDates(\n dep.type,\n predecessorStart,\n predecessorEnd,\n newStartDate,\n newEndDate,\n businessDays,\n weekendPredicate,\n task.type\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\n// START_MODULE_CONTRACT\n// PURPOSE: Propagate moved task dates through dependency and hierarchy graphs.\n// SCOPE: Dependency cascades, parent/child propagation, and business-day alignment.\n// DEPENDS: commands, dateMath, dependencies, scheduling types\n// LINKS: M-SCHEDULING, fn-cascadeByLinks, fn-universalCascade\n// ROLE: RUNTIME\n// MAP_MODE: EXPORTS\n// END_MODULE_CONTRACT\n\nimport type { Task, LinkType } from './types';\nimport {\n normalizeUTCDate,\n getTaskDuration,\n alignToWorkingDay,\n} from './dateMath';\nimport {\n calculateSuccessorDate,\n getDependencyLag,\n normalizeTaskDependencyLags,\n normalizePredecessorDates,\n} from './dependencies';\nimport {\n buildTaskRangeFromStart,\n buildTaskRangeFromEnd,\n moveTaskRange,\n} from './commands';\n\nfunction parseCascadeDateInput(date: string | Date): Date {\n if (date instanceof Date) {\n return normalizeUTCDate(date);\n }\n return normalizeUTCDate(new Date(`${date.split('T')[0]}T00:00:00.000Z`));\n}\n\nexport interface CascadeContext {\n childrenByParentId: Map<string, Task[]>;\n dependentsByPredecessorId: Map<string, Array<{ task: Task; dependencyIndex: number }>>;\n taskById: Map<string, Task>;\n}\n\nexport function createCascadeContext(allTasks: Task[]): CascadeContext {\n const childrenByParentId = new Map<string, Task[]>();\n const dependentsByPredecessorId = new Map<string, Array<{ task: Task; dependencyIndex: number }>>();\n const taskById = new Map<string, Task>();\n\n for (const task of allTasks) {\n taskById.set(task.id, task);\n\n if (task.parentId) {\n const children = childrenByParentId.get(task.parentId) ?? [];\n children.push(task);\n childrenByParentId.set(task.parentId, children);\n }\n\n if (!task.dependencies) continue;\n\n task.dependencies.forEach((dependency, dependencyIndex) => {\n const dependents = dependentsByPredecessorId.get(dependency.taskId) ?? [];\n dependents.push({ task, dependencyIndex });\n dependentsByPredecessorId.set(dependency.taskId, dependents);\n });\n }\n\n return { childrenByParentId, dependentsByPredecessorId, taskById };\n}\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 { dependentsByPredecessorId, taskById } = createCascadeContext(allTasks);\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 = dependentsByPredecessorId.get(current) ?? [];\n for (const { task } of successors) {\n if (!linkTypes.includes(task.dependencies?.find((dependency) => dependency.taskId === current)?.type ?? 'FS')) {\n continue;\n }\n const sid = task.id;\n if (!visited.has(sid)) {\n visited.add(sid);\n const successorTask = taskById.get(sid);\n if (successorTask) {\n chain.push(successorTask);\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 { childrenByParentId, dependentsByPredecessorId, taskById } = createCascadeContext(allTasks);\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 = childrenByParentId.get(currentId) ?? [];\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(normalizeTaskDependencyLags({\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 const dependents = dependentsByPredecessorId.get(currentId) ?? [];\n for (const { task, dependencyIndex } of dependents) {\n if (visited.has(task.id) || !task.dependencies || task.locked) continue;\n const dep = task.dependencies[dependencyIndex];\n if (!dep) 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 currentTask = taskById.get(currentId)!;\n const { predStart: normalizedPredStart, predEnd: normalizedPredEnd } = normalizePredecessorDates(\n {\n startDate: predStart,\n endDate: predEnd,\n type: currentTask.type,\n },\n parseCascadeDateInput\n );\n const constraintDate = calculateSuccessorDate(\n normalizedPredStart,\n normalizedPredEnd,\n dep.type,\n getDependencyLag(dep),\n false,\n undefined,\n task.type\n );\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(normalizeTaskDependencyLags({\n ...task,\n startDate: newSuccStart.toISOString().split('T')[0],\n endDate: newSuccEnd.toISOString().split('T')[0],\n }));\n queue.push(task.id);\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 { childrenByParentId, dependentsByPredecessorId } = createCascadeContext(allTasks);\n\n const directChildren = childrenByParentId.get(changedTaskId) ?? [];\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 = childrenByParentId.get(current.id) ?? [];\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 = dependentsByPredecessorId.get(current.id) ?? [];\n for (const { task: 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 context: CascadeContext = createCascadeContext(allTasks)\n): Task[] {\n const { childrenByParentId, dependentsByPredecessorId, taskById } = context;\n const normalizedMovedTask = normalizeTaskDependencyLags({\n ...movedTask,\n startDate: newStart.toISOString().split('T')[0],\n endDate: newEnd.toISOString().split('T')[0],\n });\n\n if (\n !movedTask.parentId &&\n !childrenByParentId.has(movedTask.id) &&\n !dependentsByPredecessorId.has(movedTask.id)\n ) {\n return [normalizedMovedTask];\n }\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, normalizedMovedTask);\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 = childrenByParentId.get(currentId) ?? [];\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, normalizeTaskDependencyLags({\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 // A parent move is an explicit root operation. Its requested range is the\n // authoritative move target and must not be overwritten by the derived\n // min/max wrapper rollup when its shifted children are processed.\n if (parentId && parentId !== movedTask.id) {\n const parent = taskById.get(parentId);\n if (parent && !parent.locked) {\n const siblings = childrenByParentId.get(parentId) ?? [];\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, normalizeTaskDependencyLags({\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 // A successor that was already shifted rigidly as a child (RULE 1) is part of\n // the same moving subtree — re-applying its dependency constraints here would\n // collapse the gaps/slack between descendants (e.g. a positive lag) and make\n // them drift out of the moved parent by that amount. Preserve internal offsets.\n const dependents = dependentsByPredecessorId.get(currentId) ?? [];\n for (const { task, dependencyIndex } of dependents) {\n if (task.locked || !task.dependencies) continue;\n if (childShifted.has(task.id)) continue;\n const dep = task.dependencies[dependencyIndex];\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 { predStart: normalizedPredStart, predEnd: normalizedPredEnd } = normalizePredecessorDates(\n {\n startDate: currStart,\n endDate: currEnd,\n type: currentOriginal.type,\n },\n parseCascadeDateInput\n );\n const constraintDate = calculateSuccessorDate(\n normalizedPredStart, normalizedPredEnd, dep.type, getDependencyLag(dep),\n businessDays, weekendPredicate, task.type\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, normalizeTaskDependencyLags({\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 * Hierarchy scheduling functions.\n * Moved from dependencyUtils.ts — verbatim implementations.\n * Zero React/DOM/date-fns imports.\n */\n\n// START_MODULE_CONTRACT\n// PURPOSE: Query task hierarchy and build parent/descendant progress updates.\n// SCOPE: Child/descendant lookup, parent date/progress rollups, and boundary progress batch updates.\n// DEPENDS: scheduling types\n// LINKS: M-SCHEDULE, fn-getAllDescendants, fn-cascadeTaskProgress\n// ROLE: RUNTIME\n// MAP_MODE: EXPORTS\n// END_MODULE_CONTRACT\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 * Propagate an explicit boundary progress value through a task subtree.\n *\n * Fractional parent progress is intentionally left untouched: without\n * knowing which child work was completed, there is no reliable distribution.\n * Returns the changed parent and descendants as one sparse update batch.\n */\nexport function cascadeTaskProgress(task: Task, tasks: Task[]): Task[] {\n const progress = task.progress;\n if (progress !== 0 && progress !== 100) {\n return [task];\n }\n\n const descendants = getAllDescendants(task.id, tasks);\n if (descendants.length === 0) {\n return [task];\n }\n\n return [\n { ...task, progress },\n ...descendants.map((descendant) => ({ ...descendant, progress })),\n ];\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 * Command-level scheduling API.\n * High-level functions that compose low-level scheduling primitives.\n * Zero React/DOM/date-fns imports.\n */\n\n// START_MODULE_CONTRACT\n// PURPOSE: Execute authoritative task and project schedule recalculations.\n// SCOPE: Move, resize, dependency recalculation, cascade, and full-project scheduling.\n// DEPENDS: commands, cascade, dateMath, dependencies, hierarchy, scheduling types\n// LINKS: M-SCHEDULING, fn-recalculateTaskFromDependencies, fn-recalculateProjectSchedule\n// ROLE: RUNTIME\n// MAP_MODE: EXPORTS\n// END_MODULE_CONTRACT\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, normalizePredecessorDates } 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, predEnd } = normalizePredecessorDates(predecessor, parseDateOnly);\n const constraintDate = calculateSuccessorDate(\n predStart,\n predEnd,\n dep.type,\n getDependencyLag(dep),\n businessDays,\n weekendPredicate,\n task.type\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 { predStart: predecessorStart, predEnd: predecessorEnd } = normalizePredecessorDates(predecessor, parseDateOnly);\n const constraintDate = calculateSuccessorDate(\n predecessorStart,\n predecessorEnd,\n dep.type,\n getDependencyLag(dep),\n businessDays,\n weekendPredicate,\n currentTask.type\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","import type { Task } from './types';\nimport { normalizeUTCDate, getTaskDuration, alignToWorkingDay } from './dateMath';\nimport { buildTaskRangeFromStart } from './commands';\nimport { computeParentDates, isTaskParent } from './hierarchy';\nimport { recalculateProjectSchedule } from './execute';\n\n/**\n * Recalculate all task dates when switching between business/calendar day modes.\n *\n * Mode switch semantics are not a simple per-task move:\n * 1. Leaf tasks first preserve their current duration count while snapping to\n * the target calendar rules.\n * 2. Parent tasks roll up from children.\n * 3. The full dependency graph is then recalculated in the target mode so\n * successors obey the new FS/SS/FF/SF semantics (for example Fri -> Mon in\n * business mode, Fri -> Sat in calendar mode).\n */\nexport function reflowTasksOnModeSwitch(\n sourceTasks: Task[],\n toBusinessDays: boolean,\n weekendPredicate: (date: Date) => boolean\n): Task[] {\n let tasks: Task[] = sourceTasks.map(task => ({\n ...task,\n dependencies: task.dependencies?.map(dependency => ({ ...dependency })),\n }));\n\n const toISO = (date: Date) => date.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 // Measure the duration in the TARGET mode, not the source mode. When going\n // calendar -> business (off -> on) each task must keep its BUSINESS day\n // count; counting in calendar days instead inflates every task by the\n // weekend days inside it, which pushes a task chain's tail forward past its\n // FS successor and inverts the connector.\n const duration = getTaskDuration(task.startDate, task.endDate, toBusinessDays, weekendPredicate);\n\n const range = toBusinessDays\n ? buildTaskRangeFromStart(\n alignToWorkingDay(start, 1, weekendPredicate),\n duration,\n true,\n weekendPredicate\n )\n : buildTaskRangeFromStart(start, duration, false);\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 const rescheduled = recalculateProjectSchedule(tasks, {\n businessDays: toBusinessDays,\n weekendPredicate,\n });\n\n if (rescheduled.changedTasks.length === 0) {\n return tasks;\n }\n\n const updates = new Map(rescheduled.changedTasks.map((task): [string, Task] => [task.id, task]));\n return tasks.map(task => updates.get(task.id) ?? task);\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 * Subtree duration scaling — proportional compress/stretch of a parent's subtree.\n * Zero React/DOM/date-fns imports.\n *\n * Semantics (PRD: 2026-08-23-parent-subtree-duration-scaling):\n * - Parent tasks stay computed wrappers; only leaf durations change.\n * - One common factor k scales mutable ordinary leaf durations; explicit positive\n * lags are preserved while the target is reachable via durations alone.\n * - Further compression reduces positive internal lags down to getMinLag, then\n * virtual offsets of independent components down to the anchor.\n * - Immutable tasks (locked by default) are pinned to their original dates and\n * never change any scheduling field.\n * - Milestones keep startDate === endDate and only move in time.\n * - Exact overall range wins over local proportion: a correction pass adjusts\n * one project day at a time with a provable iteration bound derived from the\n * adjustable slack (never a wall-clock timeout).\n * - Unreachable compression applies the proven minimum span and returns a\n * TARGET_CLAMPED_TO_MINIMUM warning instead of a hard error.\n *\n * The solver runs in a \"solve space\" of project-day indices where index 0 is the\n * fixed anchor boundary (original parent start for anchor:'start', the mirrored\n * original parent end for anchor:'end'). Dependency math stays in Date space\n * using the existing calculateSuccessorDate/buildTaskRange primitives, so both\n * calendar and business-day modes reuse one scheduling code path.\n */\n\n// START_MODULE_CONTRACT\n// PURPOSE: Proportionally scale a parent task subtree to an exact target duration.\n// SCOPE: Input validation, working-context indexing, pure layout evaluator,\n// duration and flexible-gap solving, date materialization with bottom-up\n// parent rollup, external dependency policies, sparse atomic result.\n// DEPENDS: scheduling types, dateMath, dependencies, commands, cascade, validation\n// LINKS: M-SCHEDULE, fn-scaleTaskSubtreeDuration, PRD-2026-08-23-parent-subtree-duration-scaling\n// ROLE: RUNTIME\n// MAP_MODE: EXPORTS\n// END_MODULE_CONTRACT\n\nimport type { LinkType, Task, TaskDependency } from './types';\nimport {\n DAY_MS,\n getBusinessDayOffset,\n getTaskDuration,\n parseDateOnly,\n shiftBusinessDayOffset,\n} from './dateMath';\nimport {\n calculateSuccessorDate,\n computeLagFromDates,\n normalizePredecessorDates,\n} from './dependencies';\nimport { buildTaskRangeFromEnd, buildTaskRangeFromStart } from './commands';\nimport { universalCascade } from './cascade';\nimport { validateDependencies } from './validation';\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\n/** Which boundary of the selected parent stays fixed during scaling. */\nexport type ScaleTaskSubtreeAnchor = 'start' | 'end';\n\n/** How dependencies leaving the subtree are handled. */\nexport type ScaleTaskSubtreeExternalPolicy = 'subtree-only' | 'cascade-successors';\n\nexport interface ScaleTaskSubtreeOptions {\n /** Fixed boundary of the parent range. Default: 'start'. */\n anchor?: ScaleTaskSubtreeAnchor;\n /** Count durations in business days via weekendPredicate. Default: false. */\n businessDays?: boolean;\n /** Weekend predicate used in business-day mode. */\n weekendPredicate?: (date: Date) => boolean;\n /**\n * External dependency policy. 'subtree-only' keeps every external task fixed\n * and fails with EXTERNAL_DEPENDENCY_CONFLICT on outgoing violations;\n * 'cascade-successors' shifts transitive external successors with preserved\n * durations. Default: 'subtree-only'.\n */\n externalDependencyPolicy?: ScaleTaskSubtreeExternalPolicy;\n /** Minimum duration override for a leaf task. Default: 1 (0 for milestones). */\n getMinDuration?: (task: Task) => number;\n /**\n * Minimum lag override for an internal positive dependency lag.\n * Default: 0. Called once per edge with the original task objects.\n */\n getMinLag?: (dependency: TaskDependency, ownerTask: Task) => number;\n /** Immutability override. Default: task.locked === true. */\n isImmutable?: (task: Task) => boolean;\n}\n\n/** Machine-readable warning attached to a successful scaling result. */\nexport type ScaleTaskSubtreeWarning =\n | {\n code: 'TARGET_CLAMPED_TO_MINIMUM';\n requestedDuration: number;\n minimumDuration: number;\n };\n\nexport type ScaleTaskSubtreeErrorCode =\n | 'INVALID_TARGET_DURATION'\n | 'TASK_NOT_FOUND'\n | 'NOT_A_PARENT'\n | 'INVALID_HIERARCHY'\n | 'INVALID_DEPENDENCIES'\n | 'INVALID_DATES'\n | 'INVALID_MINIMUM'\n | 'EXTERNAL_DEPENDENCY_CONFLICT';\n\nexport type ScaleTaskSubtreeResult =\n | {\n ok: true;\n changedTasks: Task[];\n changedIds: string[];\n requestedDuration: number;\n appliedDuration: number;\n clamped: boolean;\n warnings: ScaleTaskSubtreeWarning[];\n }\n | {\n ok: false;\n code: ScaleTaskSubtreeErrorCode;\n changedTasks: [];\n changedIds: [];\n details?: string[];\n };\n\n// ---------------------------------------------------------------------------\n// Internal model\n// ---------------------------------------------------------------------------\n\ninterface ScalingLeaf {\n id: string;\n task: Task;\n snapshotIndex: number;\n depth: number;\n isMilestone: boolean;\n immutable: boolean;\n /** Solve-space index of the original start date. */\n startIdx: number;\n /** Solve-space index of the original end date. */\n endIdx: number;\n /** Inclusive duration in project days; a milestone always occupies 1 cell. */\n duration: number;\n minDuration: number;\n componentId: number;\n isRoot: boolean;\n}\n\ninterface ScalingEdge {\n /** `${ownerTaskId}#${dependencyIndex}` — maps 1:1 onto the owner's dep entry. */\n key: string;\n predLeafId: string;\n succLeafId: string;\n type: LinkType;\n originalLag: number;\n minLag: number;\n /** Lags owned by parent tasks, immutable owners, or non-positive lags never change. */\n adjustable: boolean;\n}\n\ninterface IncomingBound {\n leafId: string;\n type: LinkType;\n lag: number;\n /** External predecessor task (never changes). */\n predTask: Task;\n}\n\ninterface OutgoingRef {\n /** Internal task id (leaf, nested parent, or the selected parent). */\n fromId: string;\n /** External successor task (owns the dependency entry). */\n succTask: Task;\n type: LinkType;\n lag: number;\n}\n\ninterface ScalingContext {\n businessDays: boolean;\n weekendPredicate?: (date: Date) => boolean;\n mirrored: boolean;\n parentTask: Task;\n snapshot: Task[];\n /** Descendant ids of the selected parent (parent excluded). */\n subtreeIds: Set<string>;\n /** Children by parent id over the whole snapshot. */\n childrenByParentId: Map<string, Task[]>;\n leaves: ScalingLeaf[];\n leafById: Map<string, ScalingLeaf>;\n /** Nested parents inside the subtree, deepest first (selected parent excluded). */\n nestedParents: Array<{ task: Task; depth: number; snapshotIndex: number }>;\n edges: ScalingEdge[];\n inEdges: Map<string, ScalingEdge[]>;\n outEdges: Map<string, ScalingEdge[]>;\n boundsByLeaf: Map<string, IncomingBound[]>;\n outgoingRefs: OutgoingRef[];\n /** Per-component floor for root offsets from parent-level FS/SS incoming deps. */\n componentFloor: Map<number, number>;\n originalSpan: number;\n /** Solver iteration budget derived from adjustable slack, not wall-clock. */\n maxCorrectionSteps: number;\n /** Resolved immutability predicate for external successor checks. */\n isImmutable: (task: Task) => boolean;\n}\n\ninterface SolverState {\n durations: Map<string, number>;\n lags: Map<string, number>;\n offsets: Map<string, number>;\n}\n\ninterface LeafRange {\n start: Date;\n end: Date;\n}\n\ninterface Layout {\n dates: Map<string, LeafRange>;\n /** Anchor-side boundary of the content extent in solve space. */\n lo: number;\n /** Far-side boundary of the content extent in solve space. */\n hi: number;\n span: number;\n}\n\nfunction toIsoDate(date: Date): string {\n return date.toISOString().split('T')[0];\n}\n\nfunction isoOfTaskDate(date: string | Date): string {\n return toIsoDate(parseDateOnly(date));\n}\n\nfunction scaleFailure(\n code: ScaleTaskSubtreeErrorCode,\n details?: string[]\n): ScaleTaskSubtreeResult {\n return details && details.length > 0\n ? { ok: false, code, changedTasks: [], changedIds: [], details }\n : { ok: false, code, changedTasks: [], changedIds: [] };\n}\n\nfunction isFiniteInteger(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value) && Number.isInteger(value);\n}\n\nfunction dependencyLag(dep: TaskDependency): number {\n return Number.isFinite(dep.lag) ? dep.lag : 0;\n}\n\n// ---------------------------------------------------------------------------\n// Solve-space conversion (index <-> date)\n// ---------------------------------------------------------------------------\n\ninterface SolveSpace {\n mirrored: boolean;\n anchorDate: Date;\n businessDays: boolean;\n weekendPredicate?: (date: Date) => boolean;\n idxCache: Map<string, number>;\n idxOf(date: Date): number;\n dateOf(idx: number): Date;\n}\n\nfunction createSolveSpace(\n mirrored: boolean,\n anchorDate: Date,\n businessDays: boolean,\n weekendPredicate?: (date: Date) => boolean\n): SolveSpace {\n const space: SolveSpace = {\n mirrored,\n anchorDate,\n businessDays,\n weekendPredicate,\n idxCache: new Map(),\n idxOf(date: Date): number {\n const key = toIsoDate(date);\n const cached = space.idxCache.get(key);\n if (cached !== undefined) {\n return cached;\n }\n let idx: number;\n if (businessDays && weekendPredicate) {\n idx = mirrored\n ? getBusinessDayOffset(date, anchorDate, weekendPredicate)\n : getBusinessDayOffset(anchorDate, date, weekendPredicate);\n } else {\n const deltaMs = date.getTime() - anchorDate.getTime();\n idx = mirrored ? -Math.round(deltaMs / DAY_MS) : Math.round(deltaMs / DAY_MS);\n }\n space.idxCache.set(key, idx);\n return idx;\n },\n dateOf(idx: number): Date {\n if (businessDays && weekendPredicate) {\n return shiftBusinessDayOffset(anchorDate, mirrored ? -idx : idx, weekendPredicate);\n }\n const delta = mirrored ? -idx : idx;\n return new Date(anchorDate.getTime() + delta * DAY_MS);\n },\n };\n return space;\n}\n\n// ---------------------------------------------------------------------------\n// Phase 1: validation\n// ---------------------------------------------------------------------------\n\n// START_BLOCK_VALIDATE_SCALE_INPUT\n\nfunction validateScaleInput(\n parentId: string,\n targetDuration: number,\n snapshot: Task[],\n businessDays: boolean,\n weekendPredicate?: (date: Date) => boolean\n): { ok: true; parentTask: Task } | { ok: false; code: ScaleTaskSubtreeErrorCode; details: string[] } {\n // 10.1 Target: finite integer >= 1.\n if (!isFiniteInteger(targetDuration) || targetDuration < 1) {\n return { ok: false, code: 'INVALID_TARGET_DURATION', details: [`targetDuration=${String(targetDuration)}`] };\n }\n\n // 10.2 Hierarchy: unique ids, resolvable parentId refs, no self-parent, no cycles.\n const taskById = new Map<string, Task>();\n const duplicateIds: string[] = [];\n for (const task of snapshot) {\n if (taskById.has(task.id)) duplicateIds.push(task.id);\n taskById.set(task.id, task);\n }\n if (duplicateIds.length > 0) {\n return { ok: false, code: 'INVALID_HIERARCHY', details: [`duplicate task ids: ${duplicateIds.slice(0, 5).join(', ')}`] };\n }\n\n const parentTask = taskById.get(parentId);\n if (!parentTask) {\n return { ok: false, code: 'TASK_NOT_FOUND', details: [`parentId=${parentId}`] };\n }\n\n const hasChild = snapshot.some((task) => task.parentId === parentId);\n if (!hasChild) {\n return { ok: false, code: 'NOT_A_PARENT', details: [`task ${parentId} has no children`] };\n }\n\n const childrenByParentId = new Map<string, Task[]>();\n const hierarchyErrors: string[] = [];\n for (const task of snapshot) {\n if (!task.parentId) continue;\n if (task.parentId === task.id) {\n hierarchyErrors.push(`self-parent: ${task.id}`);\n continue;\n }\n if (!taskById.has(task.parentId)) {\n hierarchyErrors.push(`missing parent ${task.parentId} for ${task.id}`);\n continue;\n }\n const children = childrenByParentId.get(task.parentId) ?? [];\n children.push(task);\n childrenByParentId.set(task.parentId, children);\n }\n if (hierarchyErrors.length === 0) {\n // Cycle detection: iterative walk up the parent chain with a visited guard.\n const globallyVisited = new Set<string>();\n for (const task of snapshot) {\n if (globallyVisited.has(task.id)) continue;\n const chain = new Set<string>();\n let current: Task | undefined = task;\n while (current?.parentId) {\n if (chain.has(current.id)) {\n hierarchyErrors.push(`hierarchy cycle at ${current.id}`);\n break;\n }\n chain.add(current.id);\n globallyVisited.add(current.id);\n current = taskById.get(current.parentId);\n }\n }\n }\n if (hierarchyErrors.length > 0) {\n return { ok: false, code: 'INVALID_HIERARCHY', details: hierarchyErrors.slice(0, 5) };\n }\n\n // 10.3 Dates of participating tasks: parseable, end >= start, business alignment.\n const subtreeIds = collectSubtreeIds(parentId, childrenByParentId);\n const participating = new Set<string>(subtreeIds);\n participating.add(parentId);\n // External dependency neighbours participate through bounds and outgoing checks.\n for (const task of snapshot) {\n const isInternal = subtreeIds.has(task.id) || task.id === parentId;\n for (const dep of task.dependencies ?? []) {\n if (isInternal) participating.add(dep.taskId);\n if (subtreeIds.has(dep.taskId) || dep.taskId === parentId) participating.add(task.id);\n }\n }\n\n const dateErrors: string[] = [];\n for (const id of participating) {\n const task = taskById.get(id);\n if (!task) continue;\n const start = parseDateOnly(task.startDate);\n const end = parseDateOnly(task.endDate);\n if (!Number.isFinite(start.getTime()) || !Number.isFinite(end.getTime())) {\n dateErrors.push(`unparseable dates on ${id}`);\n continue;\n }\n if (end.getTime() < start.getTime()) {\n dateErrors.push(`endDate before startDate on ${id}`);\n continue;\n }\n if (!subtreeIds.has(id)) continue;\n if (task.type === 'milestone' && start.getTime() !== end.getTime()) {\n dateErrors.push(`milestone ${id} must have equal start and end dates`);\n continue;\n }\n if (businessDays && weekendPredicate && !childrenByParentId.has(task.id)) {\n // Leaf boundaries must align to working days in business-day mode.\n if (weekendPredicate(start) || weekendPredicate(end)) {\n dateErrors.push(`leaf ${id} boundary falls on a weekend in business-day mode`);\n }\n }\n }\n if (dateErrors.length > 0) {\n return { ok: false, code: 'INVALID_DATES', details: dateErrors.slice(0, 5) };\n }\n\n // 10.4 Dependencies: existing validator covers missing endpoints, hierarchy\n // links between ancestors/descendants, and cycles.\n const depValidation = validateDependencies(snapshot);\n if (!depValidation.isValid) {\n return {\n ok: false,\n code: 'INVALID_DEPENDENCIES',\n details: depValidation.errors.slice(0, 5).map((error) => `${error.type}: ${error.taskId}`),\n };\n }\n\n return { ok: true, parentTask };\n}\n\n// END_BLOCK_VALIDATE_SCALE_INPUT\n\nfunction collectSubtreeIds(\n parentId: string,\n childrenByParentId: Map<string, Task[]>\n): Set<string> {\n const subtreeIds = new Set<string>();\n const queue = [parentId];\n while (queue.length > 0) {\n const current = queue.shift()!;\n for (const child of childrenByParentId.get(current) ?? []) {\n if (subtreeIds.has(child.id)) continue;\n subtreeIds.add(child.id);\n queue.push(child.id);\n }\n }\n return subtreeIds;\n}\n\n// ---------------------------------------------------------------------------\n// Phase 2: working context\n// ---------------------------------------------------------------------------\n\n// START_BLOCK_BUILD_SCALE_CONTEXT\n\ntype ContextBuildResult =\n | { ok: true; context: ScalingContext; space: SolveSpace }\n | { ok: false; code: ScaleTaskSubtreeErrorCode; details: string[] };\n\n/** Sentinel leaf id for parent-level incoming FS/SS bounds. */\nconst PARENT_BOUND_KEY = '__parent_bound__';\n\nfunction buildScaleContext(\n parentTask: Task,\n snapshot: Task[],\n options: ScaleTaskSubtreeOptions\n): ContextBuildResult {\n const businessDays = options.businessDays ?? false;\n const weekendPredicate = options.weekendPredicate;\n const isImmutable = options.isImmutable ?? ((task: Task) => task.locked === true);\n\n const indexedSnapshot = snapshot.map((task, index) => ({ task, index }));\n const taskById = new Map(indexedSnapshot.map(({ task }) => [task.id, task]));\n const childrenByParentId = new Map<string, Task[]>();\n for (const task of snapshot) {\n if (!task.parentId) continue;\n const children = childrenByParentId.get(task.parentId) ?? [];\n children.push(task);\n childrenByParentId.set(task.parentId, children);\n }\n\n const subtreeIds = collectSubtreeIds(parentTask.id, childrenByParentId);\n\n // Depths inside the subtree (selected parent = 0).\n const depthById = new Map<string, number>([[parentTask.id, 0]]);\n const depthQueue = [parentTask.id];\n while (depthQueue.length > 0) {\n const current = depthQueue.shift()!;\n const depth = depthById.get(current) ?? 0;\n for (const child of childrenByParentId.get(current) ?? []) {\n depthById.set(child.id, depth + 1);\n depthQueue.push(child.id);\n }\n }\n\n const subtreeTasks = indexedSnapshot.filter(({ task }) => subtreeIds.has(task.id));\n const leavesRaw = subtreeTasks.filter(({ task }) => !childrenByParentId.has(task.id));\n const nestedParentsRaw = subtreeTasks.filter(\n ({ task }) => childrenByParentId.has(task.id) && task.id !== parentTask.id\n );\n\n // The original parent range is derived from leaves bottom-up, never from the\n // stored parent dates (10.3).\n const leafEntries = leavesRaw.map(({ task, index }) => {\n const start = parseDateOnly(task.startDate);\n const end = parseDateOnly(task.endDate);\n return { task, index, start, end };\n });\n const computedStart = new Date(Math.min(...leafEntries.map((entry) => entry.start.getTime())));\n const computedEnd = new Date(Math.max(...leafEntries.map((entry) => entry.end.getTime())));\n const mirrored = (options.anchor ?? 'start') === 'end';\n const anchorDate = mirrored ? computedEnd : computedStart;\n const space = createSolveSpace(mirrored, anchorDate, businessDays, weekendPredicate);\n\n let lo = Number.POSITIVE_INFINITY;\n let hi = Number.NEGATIVE_INFINITY;\n for (const entry of leafEntries) {\n lo = Math.min(lo, space.idxOf(entry.start), space.idxOf(entry.end));\n hi = Math.max(hi, space.idxOf(entry.start), space.idxOf(entry.end));\n }\n const originalSpan = Number.isFinite(lo) ? hi - lo + 1 : 1;\n\n // Cache immutability once; user callbacks always receive original objects.\n const immutableById = new Map<string, boolean>();\n for (const { task } of subtreeTasks) {\n immutableById.set(task.id, isImmutable(task) === true);\n }\n\n // Cache and validate duration minima once (10.5).\n const getMinDuration = options.getMinDuration;\n const minDurationErrors: string[] = [];\n const minDurationById = new Map<string, number>();\n for (const { task } of subtreeTasks) {\n if (childrenByParentId.has(task.id)) continue; // leaves only\n if (task.type === 'milestone') {\n minDurationById.set(task.id, 0);\n continue;\n }\n let min = 1;\n if (getMinDuration) {\n const requested = getMinDuration(task);\n if (!isFiniteInteger(requested) || requested < 0) {\n minDurationErrors.push(`getMinDuration(${task.id}) = ${String(requested)}`);\n continue;\n }\n min = Math.max(1, requested);\n }\n minDurationById.set(task.id, min);\n }\n if (minDurationErrors.length > 0) {\n return { ok: false, code: 'INVALID_MINIMUM', details: minDurationErrors.slice(0, 5) };\n }\n\n const leaves: ScalingLeaf[] = leafEntries.map(({ task, index, start, end }) => ({\n id: task.id,\n task,\n snapshotIndex: index,\n depth: depthById.get(task.id) ?? 1,\n isMilestone: task.type === 'milestone',\n immutable: immutableById.get(task.id) === true,\n startIdx: space.idxOf(start),\n endIdx: space.idxOf(end),\n duration: getTaskDuration(start, end, businessDays, weekendPredicate),\n minDuration: minDurationById.get(task.id) ?? 1,\n componentId: -1,\n isRoot: false,\n }));\n const leafById = new Map(leaves.map((leaf) => [leaf.id, leaf]));\n\n // Anchor leaves of each nested parent (for dependency endpoint expansion).\n const anchorLeafByParent = new Map<string, { earliestStartId: string; latestEndId: string }>();\n const nestedParents: ScalingContext['nestedParents'] = nestedParentsRaw\n .map(({ task, index }) => ({ task, snapshotIndex: index, depth: depthById.get(task.id) ?? 1 }))\n .sort((left, right) => right.depth - left.depth || left.snapshotIndex - right.snapshotIndex);\n for (const { task } of nestedParents) {\n let earliestStart: ScalingLeaf | null = null;\n let latestEnd: ScalingLeaf | null = null;\n for (const leaf of leaves) {\n if (!isDescendantOf(leaf.task, task.id, taskById)) continue;\n if (!earliestStart || leaf.startIdx < earliestStart.startIdx) earliestStart = leaf;\n if (!latestEnd || leaf.endIdx > latestEnd.endIdx) latestEnd = leaf;\n }\n if (earliestStart && latestEnd) {\n anchorLeafByParent.set(task.id, { earliestStartId: earliestStart.id, latestEndId: latestEnd.id });\n }\n }\n\n // Internal edges (leaf <-> leaf after parent expansion), incoming bounds and\n // outgoing refs. Lags and minima are snapshotted exactly once.\n const getMinLag = options.getMinLag;\n const edges: ScalingEdge[] = [];\n const boundsByLeaf = new Map<string, IncomingBound[]>();\n const outgoingRefs: OutgoingRef[] = [];\n const lagErrors: string[] = [];\n\n const pushEdge = (\n ownerTask: Task,\n dep: TaskDependency,\n depIndex: number,\n predLeafId: string,\n succLeafId: string\n ) => {\n const originalLag = dependencyLag(dep);\n const succLeaf = leafById.get(succLeafId);\n const adjustable =\n originalLag > 0 &&\n !!succLeaf &&\n !succLeaf.immutable &&\n !immutableById.get(ownerTask.id);\n let minLag = originalLag;\n if (adjustable) {\n // Default minimum for a positive lag is 0 (10.5).\n minLag = 0;\n if (getMinLag) {\n const requested = getMinLag(dep, ownerTask);\n if (!isFiniteInteger(requested) || requested < 0 || requested > originalLag) {\n lagErrors.push(`getMinLag(${ownerTask.id}#${depIndex}) = ${String(requested)}`);\n } else {\n minLag = requested;\n }\n }\n }\n edges.push({\n key: `${ownerTask.id}#${depIndex}`,\n predLeafId,\n succLeafId,\n type: dep.type,\n originalLag,\n minLag,\n adjustable,\n });\n };\n\n for (const { task } of subtreeTasks) {\n if (!task.dependencies) continue;\n task.dependencies.forEach((dep, depIndex) => {\n const predTask = taskById.get(dep.taskId);\n if (!predTask) return; // missing endpoints already failed validation\n const predInside = subtreeIds.has(predTask.id);\n const isOwnerLeaf = leafById.has(task.id);\n\n if (!predInside) {\n // External incoming dependency.\n if (isOwnerLeaf) {\n const bounds = boundsByLeaf.get(task.id) ?? [];\n bounds.push({ leafId: task.id, type: dep.type, lag: dependencyLag(dep), predTask });\n boundsByLeaf.set(task.id, bounds);\n } else if (task.id === parentTask.id) {\n // Parent-level incoming FS/SS deps become component floors (10.4);\n // FF/SF parent-level deps are validated after materialization.\n if (dep.type === 'FS' || dep.type === 'SS') {\n const bounds = boundsByLeaf.get(PARENT_BOUND_KEY) ?? [];\n bounds.push({ leafId: PARENT_BOUND_KEY, type: dep.type, lag: dependencyLag(dep), predTask });\n boundsByLeaf.set(PARENT_BOUND_KEY, bounds);\n }\n } else {\n // Nested-parent incoming deps constrain the parent's boundary leaves.\n const anchors = anchorLeafByParent.get(task.id);\n if (anchors) {\n const targetLeafId =\n dep.type === 'FS' || dep.type === 'SS' ? anchors.earliestStartId : anchors.latestEndId;\n const bounds = boundsByLeaf.get(targetLeafId) ?? [];\n bounds.push({ leafId: targetLeafId, type: dep.type, lag: dependencyLag(dep), predTask });\n boundsByLeaf.set(targetLeafId, bounds);\n }\n }\n return;\n }\n\n // Internal edge: expand parent endpoints to anchor leaves.\n let predLeafId: string | undefined;\n if (leafById.has(predTask.id)) {\n predLeafId = predTask.id;\n } else {\n const anchors = anchorLeafByParent.get(predTask.id);\n if (anchors) {\n predLeafId = dep.type === 'FS' || dep.type === 'FF' ? anchors.latestEndId : anchors.earliestStartId;\n }\n }\n let succLeafId: string | undefined;\n if (isOwnerLeaf) {\n succLeafId = task.id;\n } else {\n const anchors = anchorLeafByParent.get(task.id);\n if (anchors) {\n succLeafId = dep.type === 'FS' || dep.type === 'SS' ? anchors.earliestStartId : anchors.latestEndId;\n }\n }\n if (predLeafId && succLeafId && predLeafId !== succLeafId) {\n pushEdge(task, dep, depIndex, predLeafId, succLeafId);\n }\n });\n }\n\n if (lagErrors.length > 0) {\n return { ok: false, code: 'INVALID_MINIMUM', details: lagErrors.slice(0, 5) };\n }\n\n // Outgoing refs: external successors that depend on internal tasks.\n for (const task of snapshot) {\n if (subtreeIds.has(task.id) || task.id === parentTask.id) continue;\n if (!task.dependencies) continue;\n for (const dep of task.dependencies) {\n if (!subtreeIds.has(dep.taskId) && dep.taskId !== parentTask.id) continue;\n outgoingRefs.push({ fromId: dep.taskId, succTask: task, type: dep.type, lag: dependencyLag(dep) });\n }\n }\n\n const inEdges = new Map<string, ScalingEdge[]>();\n const outEdges = new Map<string, ScalingEdge[]>();\n for (const edge of edges) {\n const inList = inEdges.get(edge.succLeafId) ?? [];\n inList.push(edge);\n inEdges.set(edge.succLeafId, inList);\n const outList = outEdges.get(edge.predLeafId) ?? [];\n outList.push(edge);\n outEdges.set(edge.predLeafId, outList);\n }\n for (const leaf of leaves) {\n leaf.isRoot = (inEdges.get(leaf.id)?.length ?? 0) === 0;\n }\n\n // Connected components over internal edges (union-find, snapshot order).\n const componentRoot = new Map<string, string>(leaves.map((leaf) => [leaf.id, leaf.id]));\n const find = (id: string): string => {\n let root = componentRoot.get(id) ?? id;\n if (root === id) return root;\n root = find(root);\n componentRoot.set(id, root);\n return root;\n };\n const union = (a: string, b: string) => {\n const ra = find(a);\n const rb = find(b);\n if (ra !== rb) componentRoot.set(ra, rb);\n };\n for (const edge of edges) union(edge.predLeafId, edge.succLeafId);\n const componentIdByRoot = new Map<string, number>();\n let componentCount = 0;\n for (const leaf of leaves) {\n const root = find(leaf.id);\n if (!componentIdByRoot.has(root)) {\n componentIdByRoot.set(root, componentCount);\n componentCount++;\n }\n leaf.componentId = componentIdByRoot.get(root)!;\n }\n\n // Component floors from parent-level incoming FS/SS bounds.\n const componentFloor = new Map<number, number>();\n const parentBounds = boundsByLeaf.get(PARENT_BOUND_KEY) ?? [];\n for (const bound of parentBounds) {\n const { predStart, predEnd } = normalizePredecessorDates(bound.predTask, parseDateOnly);\n const boundDate = calculateSuccessorDate(\n predStart,\n predEnd,\n bound.type,\n bound.lag,\n businessDays,\n weekendPredicate\n );\n const boundIdx = space.idxOf(boundDate);\n for (const leaf of leaves) {\n if (!leaf.isRoot || leaf.immutable) continue;\n componentFloor.set(leaf.componentId, Math.max(componentFloor.get(leaf.componentId) ?? 0, boundIdx));\n }\n }\n boundsByLeaf.delete(PARENT_BOUND_KEY);\n\n // Iteration budget: total adjustable days (durations + lags + offsets) plus\n // the maximum possible growth — never a wall-clock timeout.\n let adjustableTotal = 0;\n for (const leaf of leaves) {\n if (leaf.immutable || leaf.isMilestone) continue;\n adjustableTotal += Math.max(0, leaf.duration - leaf.minDuration);\n }\n for (const edge of edges) {\n if (edge.adjustable && edge.originalLag > edge.minLag) {\n adjustableTotal += edge.originalLag - edge.minLag;\n }\n }\n for (const leaf of leaves) {\n if (leaf.isRoot && !leaf.immutable) adjustableTotal += Math.max(0, leaf.startIdx);\n }\n const maxCorrectionSteps = 2 * (adjustableTotal + originalSpan) + targetBudgetGuard(originalSpan) + 64;\n\n const context: ScalingContext = {\n businessDays,\n weekendPredicate,\n mirrored,\n parentTask,\n snapshot,\n subtreeIds,\n childrenByParentId,\n leaves,\n leafById,\n nestedParents,\n edges,\n inEdges,\n outEdges,\n boundsByLeaf,\n outgoingRefs,\n componentFloor,\n originalSpan,\n maxCorrectionSteps,\n isImmutable,\n };\n\n return { ok: true, context, space };\n}\n\nfunction targetBudgetGuard(originalSpan: number): number {\n return Math.max(1, originalSpan) * 2;\n}\n\nfunction isDescendantOf(task: Task, ancestorId: string, taskById: Map<string, Task>): boolean {\n const visited = new Set<string>();\n let currentId = task.parentId;\n while (currentId) {\n if (currentId === ancestorId) return true;\n if (visited.has(currentId)) return false;\n visited.add(currentId);\n currentId = taskById.get(currentId)?.parentId;\n }\n return false;\n}\n\n// END_BLOCK_BUILD_SCALE_CONTEXT\n\n// ---------------------------------------------------------------------------\n// Phase 3: layout evaluator (pure)\n// ---------------------------------------------------------------------------\n\nfunction topoOrderLeaves(ctx: ScalingContext, componentLeaves: ScalingLeaf[]): ScalingLeaf[] {\n const byId = new Map(componentLeaves.map((leaf) => [leaf.id, leaf]));\n const indegree = new Map<string, number>(\n componentLeaves.map((leaf) => [leaf.id, 0])\n );\n for (const leaf of componentLeaves) {\n for (const edge of ctx.inEdges.get(leaf.id) ?? []) {\n if (byId.has(edge.predLeafId)) {\n indegree.set(leaf.id, (indegree.get(leaf.id) ?? 0) + 1);\n }\n }\n }\n const ready = componentLeaves\n .filter((leaf) => (indegree.get(leaf.id) ?? 0) === 0)\n .sort((left, right) => left.snapshotIndex - right.snapshotIndex);\n const ordered: ScalingLeaf[] = [];\n const emitted = new Set<string>();\n while (ready.length > 0) {\n const current = ready.shift()!;\n ordered.push(current);\n emitted.add(current.id);\n for (const edge of ctx.outEdges.get(current.id) ?? []) {\n if (!byId.has(edge.succLeafId) || emitted.has(edge.succLeafId)) continue;\n const next = (indegree.get(edge.succLeafId) ?? 0) - 1;\n indegree.set(edge.succLeafId, next);\n if (next === 0) {\n ready.push(byId.get(edge.succLeafId)!);\n ready.sort((left, right) => left.snapshotIndex - right.snapshotIndex);\n }\n }\n }\n // Cycle-free input is validated upfront; append leftovers defensively.\n for (const leaf of componentLeaves) {\n if (!emitted.has(leaf.id)) ordered.push(leaf);\n }\n return ordered;\n}\n\nfunction evaluateLayout(ctx: ScalingContext, space: SolveSpace, state: SolverState): Layout {\n const { businessDays, weekendPredicate } = ctx;\n const dates = new Map<string, LeafRange>();\n\n // Immutable leaves are pinned to their original dates.\n for (const leaf of ctx.leaves) {\n if (leaf.immutable) {\n dates.set(leaf.id, {\n start: parseDateOnly(leaf.task.startDate),\n end: parseDateOnly(leaf.task.endDate),\n });\n }\n }\n\n // Components in deterministic order (first member snapshot index).\n const componentOrder: number[] = [];\n const componentLeaves = new Map<number, ScalingLeaf[]>();\n for (const leaf of ctx.leaves) {\n const list = componentLeaves.get(leaf.componentId) ?? [];\n list.push(leaf);\n componentLeaves.set(leaf.componentId, list);\n if (list.length === 1) componentOrder.push(leaf.componentId);\n }\n\n for (const componentId of componentOrder) {\n const members = componentLeaves.get(componentId) ?? [];\n const order = topoOrderLeaves(ctx, members);\n for (const leaf of order) {\n if (dates.has(leaf.id)) continue; // pinned\n const duration = state.durations.get(leaf.id) ?? leaf.duration;\n let range: LeafRange | null = null;\n\n const incoming = ctx.inEdges.get(leaf.id) ?? [];\n if (incoming.length === 0) {\n const floor = ctx.componentFloor.get(leaf.componentId) ?? 0;\n const offset = Math.max(floor, state.offsets.get(leaf.id) ?? leaf.startIdx);\n range = buildTaskRangeFromStart(space.dateOf(offset), duration, businessDays, weekendPredicate);\n } else {\n for (const edge of incoming) {\n const predDates = dates.get(edge.predLeafId);\n if (!predDates) continue;\n const predLeaf = ctx.leafById.get(edge.predLeafId);\n const { predStart, predEnd } = normalizePredecessorDates(\n {\n startDate: predDates.start,\n endDate: predDates.end,\n type: predLeaf?.isMilestone ? ('milestone' as const) : ('task' as const),\n },\n parseDateOnly\n );\n const lag = state.lags.get(edge.key) ?? edge.originalLag;\n const constraint = calculateSuccessorDate(\n predStart,\n predEnd,\n edge.type,\n lag,\n businessDays,\n weekendPredicate,\n leaf.isMilestone ? 'milestone' : undefined\n );\n const candidate =\n edge.type === 'FS' || edge.type === 'SS'\n ? buildTaskRangeFromStart(constraint, duration, businessDays, weekendPredicate)\n : buildTaskRangeFromEnd(constraint, duration, businessDays, weekendPredicate);\n if (\n !range ||\n candidate.start.getTime() > range.start.getTime() ||\n (candidate.start.getTime() === range.start.getTime() &&\n candidate.end.getTime() > range.end.getTime())\n ) {\n range = candidate;\n }\n }\n }\n if (!range) {\n range = buildTaskRangeFromStart(space.dateOf(leaf.startIdx), duration, businessDays, weekendPredicate);\n }\n\n // Incoming external bounds: immovable lower constraints in time.\n for (const bound of ctx.boundsByLeaf.get(leaf.id) ?? []) {\n const { predStart, predEnd } = normalizePredecessorDates(bound.predTask, parseDateOnly);\n const boundDate = calculateSuccessorDate(\n predStart,\n predEnd,\n bound.type,\n bound.lag,\n businessDays,\n weekendPredicate,\n leaf.isMilestone ? 'milestone' : undefined\n );\n if ((bound.type === 'FS' || bound.type === 'SS') && range.start.getTime() < boundDate.getTime()) {\n range = buildTaskRangeFromStart(boundDate, duration, businessDays, weekendPredicate);\n } else if ((bound.type === 'FF' || bound.type === 'SF') && range.end.getTime() < boundDate.getTime()) {\n range = buildTaskRangeFromEnd(boundDate, duration, businessDays, weekendPredicate);\n }\n }\n\n // Reverse bounds: mutable predecessors must not overlap pinned successors.\n for (const edge of ctx.outEdges.get(leaf.id) ?? []) {\n const succLeaf = ctx.leafById.get(edge.succLeafId);\n if (!succLeaf || !succLeaf.immutable) continue;\n const succDates = dates.get(succLeaf.id);\n if (!succDates) continue;\n const lag = state.lags.get(edge.key) ?? edge.originalLag;\n range = applyReverseBound(\n range,\n edge.type,\n lag,\n succDates,\n succLeaf.isMilestone,\n duration,\n businessDays,\n weekendPredicate\n );\n }\n\n // Anchor-side clamp: content never crosses the fixed boundary.\n range = clampToAnchor(range, space, duration, businessDays, weekendPredicate);\n\n dates.set(leaf.id, range);\n }\n }\n\n let lo = Number.POSITIVE_INFINITY;\n let hi = Number.NEGATIVE_INFINITY;\n for (const leaf of ctx.leaves) {\n const range = dates.get(leaf.id);\n if (!range) continue;\n const startIdx = space.idxOf(range.start);\n const endIdx = space.idxOf(range.end);\n lo = Math.min(lo, startIdx, endIdx);\n hi = Math.max(hi, startIdx, endIdx);\n }\n if (!Number.isFinite(lo) || !Number.isFinite(hi)) {\n return { dates, lo: 0, hi: 0, span: 1 };\n }\n return { dates, lo, hi, span: hi - lo + 1 };\n}\n\nfunction applyReverseBound(\n range: LeafRange,\n type: LinkType,\n lag: number,\n succDates: LeafRange,\n succIsMilestone: boolean,\n duration: number,\n businessDays: boolean,\n weekendPredicate?: (date: Date) => boolean\n): LeafRange {\n const shiftBack = (date: Date, days: number): Date =>\n businessDays && weekendPredicate\n ? shiftBusinessDayOffset(date, -days, weekendPredicate)\n : new Date(date.getTime() - days * DAY_MS);\n\n switch (type) {\n case 'FS': {\n const allowedEnd = shiftBack(succDates.start, lag + (succIsMilestone ? 0 : 1));\n return range.end.getTime() > allowedEnd.getTime()\n ? buildTaskRangeFromEnd(allowedEnd, duration, businessDays, weekendPredicate)\n : range;\n }\n case 'SS': {\n const allowedStart = shiftBack(succDates.start, lag);\n return range.start.getTime() > allowedStart.getTime()\n ? buildTaskRangeFromStart(allowedStart, duration, businessDays, weekendPredicate)\n : range;\n }\n case 'FF': {\n const allowedEnd = shiftBack(succDates.end, lag);\n return range.end.getTime() > allowedEnd.getTime()\n ? buildTaskRangeFromEnd(allowedEnd, duration, businessDays, weekendPredicate)\n : range;\n }\n case 'SF': {\n const allowedStart = shiftBack(succDates.end, lag - 1);\n return range.start.getTime() > allowedStart.getTime()\n ? buildTaskRangeFromStart(allowedStart, duration, businessDays, weekendPredicate)\n : range;\n }\n }\n}\n\nfunction clampToAnchor(\n range: LeafRange,\n space: SolveSpace,\n duration: number,\n businessDays: boolean,\n weekendPredicate?: (date: Date) => boolean\n): LeafRange {\n if (!space.mirrored) {\n // Start-anchored: content never starts before the original parent start.\n if (space.idxOf(range.start) < 0) {\n return buildTaskRangeFromStart(space.anchorDate, duration, businessDays, weekendPredicate);\n }\n } else if (space.idxOf(range.end) < 0) {\n // End-anchored: content never ends after the original parent end.\n return buildTaskRangeFromEnd(space.anchorDate, duration, businessDays, weekendPredicate);\n }\n return range;\n}\n\n// ---------------------------------------------------------------------------\n// Phase 4: solving (stage A durations, correction, stage B flexible gaps)\n// ---------------------------------------------------------------------------\n\n// START_BLOCK_SOLVE_DURATIONS\n\nfunction allocateDurations(ctx: ScalingContext, target: number): Map<string, number> {\n const durations = new Map<string, number>();\n const ratio = target / Math.max(1, ctx.originalSpan);\n\n for (const leaf of ctx.leaves) {\n if (leaf.immutable || leaf.isMilestone) {\n durations.set(leaf.id, leaf.duration);\n }\n }\n\n const ideals: Array<{ leaf: ScalingLeaf; ideal: number }> = ctx.leaves\n .filter((leaf) => !leaf.immutable && !leaf.isMilestone)\n .map((leaf) => ({ leaf, ideal: Math.max(leaf.minDuration, leaf.duration * ratio) }));\n\n const minTotal = ideals.reduce((sum, { leaf }) => sum + leaf.minDuration, 0);\n const idealTotal = ideals.reduce((sum, { ideal }) => sum + ideal, 0);\n const total = Math.max(minTotal, Math.round(idealTotal));\n\n const floors = new Map<string, number>();\n let floorTotal = 0;\n for (const { leaf, ideal } of ideals) {\n const floor = Math.max(leaf.minDuration, Math.floor(ideal));\n floors.set(leaf.id, floor);\n floorTotal += floor;\n }\n\n // Largest remainder with deterministic tie-break: larger fraction first,\n // then earlier original start, then id.\n let remaining = Math.max(0, total - floorTotal);\n const byFraction = [...ideals].sort((left, right) => {\n const fracLeft = left.ideal - (floors.get(left.leaf.id) ?? 0);\n const fracRight = right.ideal - (floors.get(right.leaf.id) ?? 0);\n if (fracLeft !== fracRight) return fracRight - fracLeft;\n const timeLeft = isoOfTaskDate(left.leaf.task.startDate);\n const timeRight = isoOfTaskDate(right.leaf.task.startDate);\n if (timeLeft !== timeRight) return timeLeft < timeRight ? -1 : 1;\n return left.leaf.id < right.leaf.id ? -1 : 1;\n });\n for (const { leaf } of byFraction) {\n if (remaining <= 0) break;\n floors.set(leaf.id, (floors.get(leaf.id) ?? 0) + 1);\n remaining -= 1;\n }\n\n for (const { leaf } of ideals) {\n durations.set(leaf.id, floors.get(leaf.id) ?? leaf.duration);\n }\n return durations;\n}\n\n// END_BLOCK_SOLVE_DURATIONS\n\n// START_BLOCK_SOLVE_FLEXIBLE_GAPS\n\ninterface SolveOutcome {\n state: SolverState;\n layout: Layout;\n appliedSpan: number;\n clamped: boolean;\n}\n\nfunction solveScale(ctx: ScalingContext, space: SolveSpace, target: number): SolveOutcome {\n const state: SolverState = {\n durations: allocateDurations(ctx, target),\n lags: new Map(ctx.edges.map((edge) => [edge.key, edge.originalLag])),\n offsets: new Map(\n ctx.leaves\n .filter((leaf) => leaf.isRoot && !leaf.immutable)\n .map((leaf) => {\n const floor = ctx.componentFloor.get(leaf.componentId) ?? 0;\n const scaled = Math.round((leaf.startIdx * target) / Math.max(1, ctx.originalSpan));\n return [leaf.id, Math.max(floor, scaled)] as const;\n })\n ),\n };\n\n let layout = evaluateLayout(ctx, space, state);\n let exhausted = false;\n let steps = 0;\n\n while (layout.span !== target && steps < ctx.maxCorrectionSteps) {\n steps++;\n if (layout.span > target) {\n if (tryFirstImprovementReduce(ctx, space, state, layout)) {\n layout = evaluateLayout(ctx, space, state);\n continue;\n }\n if (exhausted) break;\n // Stage B exhaustion: durations to minima, positive lags to minima,\n // virtual offsets to their floors — the proven minimum layout.\n exhausted = true;\n exhaustFlexibleGaps(ctx, state);\n layout = evaluateLayout(ctx, space, state);\n continue;\n }\n if (tryGrow(ctx, space, state, layout, target)) {\n layout = evaluateLayout(ctx, space, state);\n continue;\n }\n break;\n }\n\n // Align the anchor-side boundary (index 0) when the layout allows it.\n layout = alignAnchorBoundary(ctx, space, state, layout);\n\n return {\n state,\n layout,\n appliedSpan: layout.span,\n clamped: layout.span > target,\n };\n}\n\nfunction farBoundaryKey(\n leaf: ScalingLeaf,\n dates: Map<string, LeafRange>,\n space: SolveSpace\n): number {\n const range = dates.get(leaf.id);\n if (!range) return Math.max(leaf.startIdx, leaf.endIdx);\n return Math.max(space.idxOf(range.start), space.idxOf(range.end));\n}\n\nfunction tryFirstImprovementReduce(\n ctx: ScalingContext,\n space: SolveSpace,\n state: SolverState,\n layout: Layout\n): boolean {\n // 1. Durations of boundary-defining mutable ordinary leaves.\n const durationCandidates = ctx.leaves\n .filter(\n (leaf) =>\n !leaf.immutable &&\n !leaf.isMilestone &&\n (state.durations.get(leaf.id) ?? leaf.duration) > leaf.minDuration\n )\n .sort(\n (left, right) =>\n farBoundaryKey(right, layout.dates, space) - farBoundaryKey(left, layout.dates, space) ||\n left.snapshotIndex - right.snapshotIndex\n );\n for (const leaf of durationCandidates) {\n const current = state.durations.get(leaf.id) ?? leaf.duration;\n state.durations.set(leaf.id, current - 1);\n const next = evaluateLayout(ctx, space, state);\n if (next.span < layout.span) return true;\n state.durations.set(leaf.id, current);\n }\n\n // 2. Positive internal explicit lags (durations are exhausted at this point).\n const lagCandidates = ctx.edges\n .filter((edge) => edge.adjustable && (state.lags.get(edge.key) ?? edge.originalLag) > edge.minLag)\n .sort((left, right) => {\n const succLeft = ctx.leafById.get(left.succLeafId)?.snapshotIndex ?? 0;\n const succRight = ctx.leafById.get(right.succLeafId)?.snapshotIndex ?? 0;\n if (succLeft !== succRight) return succLeft - succRight;\n return left.key < right.key ? -1 : 1;\n });\n for (const edge of lagCandidates) {\n const current = state.lags.get(edge.key) ?? edge.originalLag;\n state.lags.set(edge.key, current - 1);\n const next = evaluateLayout(ctx, space, state);\n if (next.span < layout.span) return true;\n state.lags.set(edge.key, current);\n }\n\n // 3. Virtual offsets of independent component roots.\n const offsetCandidates = ctx.leaves\n .filter((leaf) => leaf.isRoot && !leaf.immutable)\n .map((leaf) => ({ leaf, offset: state.offsets.get(leaf.id) ?? leaf.startIdx }))\n .filter(({ leaf, offset }) => offset > (ctx.componentFloor.get(leaf.componentId) ?? 0))\n .sort(\n (left, right) =>\n right.offset - left.offset || left.leaf.snapshotIndex - right.leaf.snapshotIndex\n );\n for (const { leaf, offset } of offsetCandidates) {\n state.offsets.set(leaf.id, offset - 1);\n const next = evaluateLayout(ctx, space, state);\n if (next.span < layout.span) return true;\n state.offsets.set(leaf.id, offset);\n }\n\n return false;\n}\n\nfunction exhaustFlexibleGaps(ctx: ScalingContext, state: SolverState): void {\n for (const leaf of ctx.leaves) {\n if (leaf.immutable || leaf.isMilestone) continue;\n state.durations.set(leaf.id, leaf.minDuration);\n }\n for (const edge of ctx.edges) {\n if (edge.adjustable) {\n state.lags.set(edge.key, edge.minLag);\n }\n }\n for (const leaf of ctx.leaves) {\n if (!leaf.isRoot || leaf.immutable) continue;\n state.offsets.set(leaf.id, ctx.componentFloor.get(leaf.componentId) ?? 0);\n }\n}\n\nfunction tryGrow(\n ctx: ScalingContext,\n space: SolveSpace,\n state: SolverState,\n layout: Layout,\n target: number\n): boolean {\n const growthCandidates = ctx.leaves\n .filter((leaf) => !leaf.immutable && !leaf.isMilestone)\n .sort(\n (left, right) =>\n farBoundaryKey(right, layout.dates, space) - farBoundaryKey(left, layout.dates, space) ||\n left.snapshotIndex - right.snapshotIndex\n );\n for (const leaf of growthCandidates) {\n const current = state.durations.get(leaf.id) ?? leaf.duration;\n state.durations.set(leaf.id, current + 1);\n const next = evaluateLayout(ctx, space, state);\n if (next.span > layout.span && next.span <= target) return true;\n state.durations.set(leaf.id, current);\n }\n\n // Grow offsets of the farthest independent roots (e.g. milestone-only subtrees).\n const offsetCandidates = ctx.leaves\n .filter((leaf) => leaf.isRoot && !leaf.immutable)\n .map((leaf) => ({ leaf, offset: state.offsets.get(leaf.id) ?? leaf.startIdx }))\n .sort(\n (left, right) =>\n right.offset - left.offset || left.leaf.snapshotIndex - right.leaf.snapshotIndex\n );\n for (const { leaf, offset } of offsetCandidates) {\n state.offsets.set(leaf.id, offset + 1);\n const next = evaluateLayout(ctx, space, state);\n if (next.span > layout.span && next.span <= target) return true;\n state.offsets.set(leaf.id, offset);\n }\n return false;\n}\n\nfunction alignAnchorBoundary(\n ctx: ScalingContext,\n space: SolveSpace,\n state: SolverState,\n layout: Layout\n): Layout {\n if (layout.lo === 0) return layout;\n if (ctx.leaves.some((leaf) => leaf.immutable)) return layout;\n if (ctx.boundsByLeaf.size > 0) return layout;\n if (ctx.componentFloor.size > 0) return layout;\n\n const roots = ctx.leaves.filter((leaf) => leaf.isRoot && !leaf.immutable);\n if (roots.length === 0) return layout;\n const minOffset = Math.min(\n ...roots.map((leaf) => state.offsets.get(leaf.id) ?? leaf.startIdx)\n );\n if (minOffset <= 0) return layout;\n const shift = Math.min(layout.lo, minOffset);\n if (shift <= 0) return layout;\n\n const backup = new Map(state.offsets);\n for (const leaf of roots) {\n state.offsets.set(leaf.id, (state.offsets.get(leaf.id) ?? leaf.startIdx) - shift);\n }\n const next = evaluateLayout(ctx, space, state);\n if (next.span === layout.span && next.lo < layout.lo) {\n return next;\n }\n state.offsets.clear();\n for (const [key, value] of backup) state.offsets.set(key, value);\n return layout;\n}\n\n// END_BLOCK_SOLVE_FLEXIBLE_GAPS\n\n// ---------------------------------------------------------------------------\n// Phase 5: materialization + external policies + sparse result\n// ---------------------------------------------------------------------------\n\n// START_BLOCK_MATERIALIZE_SCALE_RESULT\n\n/**\n * Build the leaf's next dependency list: internal lags take the solved values,\n * external incoming lags are recalculated from the final dates. Returns null\n * when nothing changed.\n */\nfunction buildLeafDependencies(\n leaf: ScalingLeaf,\n range: LeafRange,\n finalDates: Map<string, LeafRange>,\n taskById: Map<string, Task>,\n state: SolverState,\n ctx: ScalingContext,\n space: SolveSpace\n): TaskDependency[] | null {\n const deps = leaf.task.dependencies;\n if (!deps || deps.length === 0) return null;\n let changed = false;\n const nextDeps = deps.map((dep, depIndex) => {\n const key = `${leaf.id}#${depIndex}`;\n const solvedLag = state.lags.get(key);\n if (solvedLag !== undefined && solvedLag !== dependencyLag(dep)) {\n changed = true;\n return { ...dep, lag: solvedLag };\n }\n const predTask = taskById.get(dep.taskId);\n if (!predTask) return { ...dep, lag: dependencyLag(dep) };\n if (ctx.subtreeIds.has(predTask.id)) {\n // Internal edge without a solver entry (e.g. collapsed expansion): keep it.\n return { ...dep, lag: dependencyLag(dep) };\n }\n // External predecessor: reflect the actual final gap.\n const predRange = finalDates.get(predTask.id);\n const { predStart, predEnd } = normalizePredecessorDates(\n {\n startDate: predRange ? predRange.start : parseDateOnly(predTask.startDate),\n endDate: predRange ? predRange.end : parseDateOnly(predTask.endDate),\n type: predTask.type,\n },\n parseDateOnly\n );\n const lag = computeLagFromDates(\n dep.type,\n predStart,\n predEnd,\n range.start,\n range.end,\n ctx.businessDays,\n ctx.weekendPredicate,\n leaf.isMilestone ? 'milestone' : undefined\n );\n if (lag !== dependencyLag(dep)) changed = true;\n return { ...dep, lag };\n });\n void space;\n return changed ? nextDeps : null;\n}\n\nfunction buildFinalTasks(\n ctx: ScalingContext,\n state: SolverState,\n layout: Layout,\n space: SolveSpace\n): Map<string, Task> {\n const taskById = new Map(ctx.snapshot.map((task) => [task.id, task]));\n const finalTasks = new Map<string, Task>();\n\n // Leaves: new dates + updated dependency lags for mutable leaves.\n for (const leaf of ctx.leaves) {\n if (leaf.immutable) continue;\n const range = layout.dates.get(leaf.id);\n if (!range) continue;\n const newStart = toIsoDate(range.start);\n const newEnd = toIsoDate(range.end);\n const startChanged = newStart !== isoOfTaskDate(leaf.task.startDate);\n const endChanged = newEnd !== isoOfTaskDate(leaf.task.endDate);\n const nextDeps = buildLeafDependencies(leaf, range, layout.dates, taskById, state, ctx, space);\n if (!startChanged && !endChanged && !nextDeps) continue;\n finalTasks.set(leaf.id, {\n ...leaf.task,\n startDate: newStart,\n endDate: newEnd,\n ...(nextDeps ? { dependencies: nextDeps } : {}),\n });\n }\n\n // Nested parents, deepest first: roll up from direct children.\n for (const { task } of ctx.nestedParents) {\n const children = ctx.childrenByParentId.get(task.id) ?? [];\n let minStart: Date | null = null;\n let maxEnd: Date | null = null;\n for (const child of children) {\n const childFinal = finalTasks.get(child.id);\n const start = parseDateOnly(childFinal ? childFinal.startDate : child.startDate);\n const end = parseDateOnly(childFinal ? childFinal.endDate : child.endDate);\n if (!minStart || start.getTime() < minStart.getTime()) minStart = start;\n if (!maxEnd || end.getTime() > maxEnd.getTime()) maxEnd = end;\n }\n if (!minStart || !maxEnd) continue;\n const newStart = toIsoDate(minStart);\n const newEnd = toIsoDate(maxEnd);\n if (newStart === isoOfTaskDate(task.startDate) && newEnd === isoOfTaskDate(task.endDate)) {\n continue;\n }\n finalTasks.set(task.id, { ...task, startDate: newStart, endDate: newEnd });\n }\n\n // Selected parent: roll up from its direct children; dependencies untouched.\n const parentChildren = ctx.childrenByParentId.get(ctx.parentTask.id) ?? [];\n let parentStart: Date | null = null;\n let parentEnd: Date | null = null;\n for (const child of parentChildren) {\n const childFinal = finalTasks.get(child.id);\n const start = parseDateOnly(childFinal ? childFinal.startDate : child.startDate);\n const end = parseDateOnly(childFinal ? childFinal.endDate : child.endDate);\n if (!parentStart || start.getTime() < parentStart.getTime()) parentStart = start;\n if (!parentEnd || end.getTime() > parentEnd.getTime()) parentEnd = end;\n }\n if (parentStart && parentEnd) {\n const newStart = toIsoDate(parentStart);\n const newEnd = toIsoDate(parentEnd);\n if (\n newStart !== isoOfTaskDate(ctx.parentTask.startDate) ||\n newEnd !== isoOfTaskDate(ctx.parentTask.endDate)\n ) {\n finalTasks.set(ctx.parentTask.id, {\n ...ctx.parentTask,\n startDate: newStart,\n endDate: newEnd,\n });\n }\n }\n\n return finalTasks;\n}\n\nfunction findOutgoingViolations(\n ctx: ScalingContext,\n finalTasks: Map<string, Task>\n): string[] {\n const violations: string[] = [];\n const originalById = new Map(ctx.snapshot.map((task) => [task.id, task]));\n for (const ref of ctx.outgoingRefs) {\n const fromTask = finalTasks.get(ref.fromId) ?? originalById.get(ref.fromId);\n if (!fromTask) continue;\n const { predStart, predEnd } = normalizePredecessorDates(fromTask, parseDateOnly);\n const required = calculateSuccessorDate(\n predStart,\n predEnd,\n ref.type,\n ref.lag,\n ctx.businessDays,\n ctx.weekendPredicate,\n ref.succTask.type === 'milestone' ? 'milestone' : undefined\n );\n const succStart = parseDateOnly(ref.succTask.startDate);\n const succEnd =\n ref.succTask.type === 'milestone' ? succStart : parseDateOnly(ref.succTask.endDate);\n if (ref.type === 'FS' || ref.type === 'SS') {\n if (succStart.getTime() < required.getTime()) {\n violations.push(`${ref.type} ${ref.fromId} -> ${ref.succTask.id}`);\n }\n } else if (succEnd.getTime() < required.getTime()) {\n violations.push(`${ref.type} ${ref.fromId} -> ${ref.succTask.id}`);\n }\n }\n return violations;\n}\n\nfunction cascadeExternalSuccessors(\n ctx: ScalingContext,\n finalTasks: Map<string, Task>\n): { ok: true; changedExternal: Task[] } | { ok: false; details: string[] } {\n // Immutable external successors cancel the whole operation.\n const immutableExternal = new Set<string>();\n const seeds: string[] = [];\n for (const ref of ctx.outgoingRefs) {\n if (ctx.isImmutable(ref.succTask) || ref.succTask.locked === true) {\n immutableExternal.add(ref.succTask.id);\n }\n if (finalTasks.has(ref.fromId) && !seeds.includes(ref.fromId)) {\n seeds.push(ref.fromId);\n }\n }\n if (immutableExternal.size > 0) {\n return {\n ok: false,\n details: [`immutable external successor(s): ${[...immutableExternal].slice(0, 5).join(', ')}`],\n };\n }\n if (seeds.length === 0) return { ok: true, changedExternal: [] };\n\n // Working snapshot with all subtree changes applied; externals copied.\n const working = ctx.snapshot.map((task) => {\n const final = finalTasks.get(task.id);\n return final ?? { ...task };\n });\n\n const externalChanged = new Map<string, Task>();\n for (const seedId of seeds) {\n const seedTask = working.find((task) => task.id === seedId);\n if (!seedTask) continue;\n const cascade = universalCascade(\n seedTask,\n parseDateOnly(seedTask.startDate),\n parseDateOnly(seedTask.endDate),\n working,\n ctx.businessDays,\n ctx.weekendPredicate\n );\n for (const updated of cascade) {\n if (ctx.subtreeIds.has(updated.id) || updated.id === ctx.parentTask.id) continue;\n const beforeIndex = working.findIndex((task) => task.id === updated.id);\n if (beforeIndex < 0) continue;\n const before = working[beforeIndex];\n if (JSON.stringify(before) !== JSON.stringify(updated)) {\n externalChanged.set(updated.id, updated);\n }\n working.splice(beforeIndex, 1, updated);\n }\n }\n\n // Deterministic topological order over the changed external set.\n const changedSet = new Set(externalChanged.keys());\n const indegree = new Map<string, number>([...changedSet].map((id) => [id, 0]));\n for (const task of externalChanged.values()) {\n for (const dep of task.dependencies ?? []) {\n if (changedSet.has(dep.taskId)) {\n indegree.set(task.id, (indegree.get(task.id) ?? 0) + 1);\n }\n }\n }\n const snapshotIndexById = new Map(ctx.snapshot.map((task, index) => [task.id, index]));\n const ready = [...changedSet]\n .filter((id) => (indegree.get(id) ?? 0) === 0)\n .sort((left, right) => (snapshotIndexById.get(left) ?? 0) - (snapshotIndexById.get(right) ?? 0));\n const ordered: Task[] = [];\n const emitted = new Set<string>();\n while (ready.length > 0) {\n const currentId = ready.shift()!;\n const current = externalChanged.get(currentId)!;\n ordered.push(current);\n emitted.add(currentId);\n for (const [otherId, other] of externalChanged) {\n if (emitted.has(otherId)) continue;\n if (!(other.dependencies ?? []).some((dep) => dep.taskId === currentId)) continue;\n const next = (indegree.get(otherId) ?? 0) - 1;\n indegree.set(otherId, next);\n if (next === 0) {\n ready.push(otherId);\n ready.sort((left, right) => (snapshotIndexById.get(left) ?? 0) - (snapshotIndexById.get(right) ?? 0));\n }\n }\n }\n for (const id of changedSet) {\n if (!emitted.has(id)) ordered.push(externalChanged.get(id)!);\n }\n\n return { ok: true, changedExternal: ordered };\n}\n\n// END_BLOCK_MATERIALIZE_SCALE_RESULT\n\n// START_BLOCK_VALIDATE_SCALE_RESULT\n\nfunction validateFinalGraph(\n ctx: ScalingContext,\n finalTasks: Map<string, Task>,\n external: Task[]\n): string[] {\n if (finalTasks.size === 0 && external.length === 0) return [];\n const updates = new Map<string, Task>();\n for (const task of finalTasks.values()) updates.set(task.id, task);\n for (const task of external) updates.set(task.id, task);\n const finalSnapshot = ctx.snapshot.map((task) => updates.get(task.id) ?? task);\n const validation = validateDependencies(finalSnapshot);\n return validation.isValid\n ? []\n : validation.errors.slice(0, 5).map((error) => `${error.type}: ${error.taskId}`);\n}\n\n// END_BLOCK_VALIDATE_SCALE_RESULT\n\n// ---------------------------------------------------------------------------\n// Public operation\n// ---------------------------------------------------------------------------\n\n/**\n * Proportionally scale a parent task's subtree to an exact target duration.\n *\n * The input snapshot is never mutated; the operation returns one atomic batch\n * of changed tasks. Unreachable compression targets apply the proven minimum\n * span and report a TARGET_CLAMPED_TO_MINIMUM warning instead of failing.\n */\nexport function scaleTaskSubtreeDuration(\n parentId: string,\n targetDuration: number,\n snapshot: Task[],\n options?: ScaleTaskSubtreeOptions\n): ScaleTaskSubtreeResult {\n const resolvedOptions = options ?? {};\n const businessDays = resolvedOptions.businessDays ?? false;\n\n // Phase 1: validate before any computation.\n const validation = validateScaleInput(\n parentId,\n targetDuration,\n snapshot,\n businessDays,\n resolvedOptions.weekendPredicate\n );\n if (!validation.ok) {\n return scaleFailure(validation.code, validation.details);\n }\n\n // Phase 2: build the indexed working context.\n const built = buildScaleContext(validation.parentTask, snapshot, resolvedOptions);\n if (!built.ok) {\n return scaleFailure(built.code, built.details);\n }\n const { context: ctx, space } = built;\n\n // Phases 3-4: solve durations, then flexible gaps, with exact-range correction.\n const solved = solveScale(ctx, space, targetDuration);\n\n // Phase 5: materialize dates, roll up parents, apply external policy.\n const finalTasks = buildFinalTasks(ctx, solved.state, solved.layout, space);\n\n const externalPolicy = resolvedOptions.externalDependencyPolicy ?? 'subtree-only';\n let externalChanged: Task[] = [];\n if (externalPolicy === 'subtree-only') {\n const violations = findOutgoingViolations(ctx, finalTasks);\n if (violations.length > 0) {\n return scaleFailure('EXTERNAL_DEPENDENCY_CONFLICT', violations);\n }\n } else {\n const cascaded = cascadeExternalSuccessors(ctx, finalTasks);\n if (!cascaded.ok) {\n return scaleFailure('EXTERNAL_DEPENDENCY_CONFLICT', cascaded.details);\n }\n externalChanged = cascaded.changedExternal;\n }\n\n // Final validation of the produced graph.\n const finalErrors = validateFinalGraph(ctx, finalTasks, externalChanged);\n if (finalErrors.length > 0) {\n return scaleFailure('INVALID_DEPENDENCIES', finalErrors);\n }\n\n // Sparse result in canonical order:\n // 1. changed leaves in snapshot order,\n // 2. changed nested parents from deepest to the selected parent,\n // 3. external cascaded successors in topological order.\n const changedLeaves = ctx.leaves\n .filter((leaf) => finalTasks.has(leaf.id))\n .map((leaf) => finalTasks.get(leaf.id)!);\n const changedParents = [...ctx.nestedParents.map(({ task }) => task), ctx.parentTask]\n .filter((task) => finalTasks.has(task.id))\n .map((task) => finalTasks.get(task.id)!);\n\n const changedTasks = [...changedLeaves, ...changedParents, ...externalChanged];\n const seen = new Set<string>();\n const uniqueChanged = changedTasks.filter((task) => {\n if (seen.has(task.id)) return false;\n seen.add(task.id);\n return true;\n });\n\n const warnings: ScaleTaskSubtreeWarning[] = solved.clamped\n ? [\n {\n code: 'TARGET_CLAMPED_TO_MINIMUM' as const,\n requestedDuration: targetDuration,\n minimumDuration: solved.appliedSpan,\n },\n ]\n : [];\n\n return {\n ok: true,\n changedTasks: uniqueChanged,\n changedIds: uniqueChanged.map((task) => task.id),\n requestedDuration: targetDuration,\n appliedDuration: solved.appliedSpan,\n clamped: solved.clamped,\n warnings,\n };\n}\n"],"mappings":"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","names":["DAY_MS","DAY_MS","toIsoDate"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/core/scheduling/index.ts","../../../src/core/scheduling/dateMath.ts","../../../src/core/scheduling/dependencies.ts","../../../src/core/scheduling/criticalPath.ts","../../../src/core/scheduling/commands.ts","../../../src/core/scheduling/cascade.ts","../../../src/core/scheduling/hierarchy.ts","../../../src/core/scheduling/execute.ts","../../../src/core/scheduling/modeSwitch.ts","../../../src/core/scheduling/validation.ts","../../../src/core/scheduling/subtreeScaling.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 './criticalPath';\nexport * from './cascade';\nexport * from './modeSwitch';\nexport * from './commands';\nexport * from './execute';\nexport * from './validation';\nexport * from './hierarchy';\nexport * from './subtreeScaling';\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\n// START_MODULE_CONTRACT\n// PURPOSE: Calculate dependency dates and lags using inclusive task dates and explicit milestone semantics.\n// SCOPE: Normalize dependency inputs, calculate successor anchors, and derive lag values from task ranges.\n// DEPENDS: dateMath, scheduling types\n// LINKS: M-SCHEDULING, fn-calculateSuccessorDate, fn-computeLagFromDates\n// ROLE: RUNTIME\n// MAP_MODE: EXPORTS\n// END_MODULE_CONTRACT\n\nimport type { LinkType, TaskDependency, Task } from './types';\nimport {\n getBusinessDayOffset,\n shiftBusinessDayOffset,\n DAY_MS,\n getTaskDuration,\n} from './dateMath';\n\n/**\n * Normalize predecessor dates for scheduling calculations.\n * Milestones have a real zero-duration finish anchor at startDate. The\n * successor type, rather than a fabricated predecessor date, determines\n * whether FS lag=0 lands on the same day (milestone successor) or the next\n * day (regular successor).\n */\nexport function normalizePredecessorDates(\n predecessor: Pick<Task, 'startDate' | 'endDate' | 'type'>,\n parseDateFn: (d: string | Date) => Date\n): { predStart: Date; predEnd: Date } {\n const predStart = parseDateFn(predecessor.startDate);\n const predEnd = predecessor.type === 'milestone'\n ? predStart\n : parseDateFn(predecessor.endDate);\n return { predStart, predEnd };\n}\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 * Return a copy of a task with dependency lag values normalized.\n *\n * FS lag normalization depends on predecessor duration, so this helper\n * intentionally leaves dependencies unchanged.\n */\nexport function normalizeTaskDependencyLags<TTask extends Pick<Task, 'dependencies'>>(task: TTask): TTask {\n return task;\n}\n\n/**\n * Normalize lag for FS links. Regular successors clamp to\n * `-predecessorDuration`; milestone successors use one fewer day because\n * their zero-duration FS anchor is the predecessor finish date itself.\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 successorType?: Task['type']\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 const minimumLag = successorType === 'milestone'\n ? -(Math.max(0, predecessorDuration - 1))\n : -predecessorDuration;\n\n return Math.max(minimumLag, 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 regular-task days = 0)\n * milestone successor uses succStart - predEnd (same-day = 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 successorType?: Task['type']\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) - (successorType === 'milestone' ? 0 : 1),\n predStart,\n predEnd,\n businessDays,\n weekendPredicate,\n successorType\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 - (successorType === 'milestone' ? 0 : 1),\n predStart,\n predEnd,\n businessDays,\n weekendPredicate,\n successorType\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 for regular tasks\n * and Predecessor end + lag for milestone successors\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 successorType?: Task['type']\n): Date {\n const normalizedLag = normalizeDependencyLag(\n linkType,\n lag,\n predecessorStart,\n predecessorEnd,\n businessDays,\n weekendPredicate,\n successorType\n );\n\n // Calendar days (original logic)\n if (!businessDays || !weekendPredicate) {\n switch (linkType) {\n case 'FS':\n return new Date(predecessorEnd.getTime() + (\n normalizedLag + (successorType === 'milestone' ? 0 : 1)\n ) * 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 + (successorType === 'milestone' ? 0 : 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 * Critical path (CPM) calculation over dependency links.\n * Zero React/DOM/date-fns imports.\n *\n * Semantics:\n * - Only leaf tasks (no task references them as parentId) participate in the graph.\n * - All link types are edges — FS, SS, FF, SF — with calendar lags, mirroring\n * calculateSuccessorDate:\n * FS: succStart >= predEnd + lag SS: succStart >= predStart + lag\n * FF: succEnd >= predEnd + lag SF: succEnd >= predStart + lag\n * - A dependency on a parent task (a task that has children) is expanded to its\n * leaf descendants with the same link type and lag. For finish-anchored links\n * (FS/FF) the group is bounded by its latest-finishing leaf; for start-anchored\n * links (SS/SF) by its latest-starting leaf — a conservative approximation of\n * the group's span.\n * - Task weight = business-day duration (getTaskDuration); edge weight = lag in the\n * active scheduling unit.\n * - The scheduled task dates are used as the current starts. The project finish is\n * the latest scheduled leaf finish, so a late short branch can be critical even\n * when a longer branch started earlier.\n * - Task is critical when its total float (late start - scheduled start) is <= 0.\n * A standalone task can therefore be critical when it determines the project\n * finish; dependency membership is not a prerequisite for criticality.\n * - Cycles are skipped by topological ordering (Kahn) — cyclic tasks are not critical.\n */\n\nimport type { ScheduleTask, LinkType } from './types';\nimport { DAY_MS, getBusinessDayOffset, getTaskDuration, parseDateOnly } from './dateMath';\nimport { getDependencyLag } from './dependencies';\n\nexport interface CriticalPathOptions {\n businessDays?: boolean;\n weekendPredicate?: (date: Date) => boolean;\n}\n\ninterface Edge {\n succId: string;\n lag: number;\n type: LinkType;\n}\n\nexport function computeCriticalPath(\n tasks: ScheduleTask[],\n options: CriticalPathOptions = {}\n): Set<string> {\n const { businessDays = false, weekendPredicate } = options;\n\n const taskById = new Map(tasks.map((task) => [task.id, task]));\n\n const childIds = new Set<string>();\n for (const task of tasks) {\n if (task.parentId) childIds.add(task.parentId);\n }\n const leafTasks = tasks.filter((task) => !childIds.has(task.id));\n const leafIds = new Set(leafTasks.map((task) => task.id));\n\n // Map any task id (parent or not) to ALL of its leaf descendants (transitive).\n const leafIdsByAncestor = new Map<string, Set<string>>();\n for (const leaf of leafTasks) {\n let ancestor: string | undefined = leaf.parentId;\n while (ancestor) {\n const set = leafIdsByAncestor.get(ancestor) ?? new Set<string>();\n set.add(leaf.id);\n leafIdsByAncestor.set(ancestor, set);\n ancestor = taskById.get(ancestor)?.parentId;\n }\n }\n\n const durationOf = (task: ScheduleTask): number =>\n getTaskDuration(task.startDate, task.endDate, businessDays, weekendPredicate);\n\n const projectStartDate = leafTasks.reduce((earliest, task) => {\n const taskStart = parseDateOnly(task.startDate);\n return taskStart.getTime() < earliest.getTime() ? taskStart : earliest;\n }, parseDateOnly(leafTasks[0]?.startDate ?? new Date()));\n\n const offsetFromProjectStart = (date: string | Date): number => {\n const targetDate = parseDateOnly(date);\n if (businessDays && weekendPredicate) {\n return getBusinessDayOffset(projectStartDate, targetDate, weekendPredicate);\n }\n return Math.round((targetDate.getTime() - projectStartDate.getTime()) / DAY_MS);\n };\n\n // The current schedule is the forward pass. Do not reset every root task to\n // day zero: its actual start date is what gives it (or removes) total float.\n const scheduledStart = new Map<string, number>();\n for (const leaf of leafTasks) {\n scheduledStart.set(leaf.id, offsetFromProjectStart(leaf.startDate));\n }\n\n // Adjacency over all link types: predecessor -> successors, successor -> predecessors.\n const succByPred = new Map<string, Edge[]>();\n const predBySucc = new Map<string, Array<{ predId: string; lag: number; type: LinkType }>>();\n const seenEdges = new Set<string>();\n\n const addEdge = (predecessorId: string, succId: string, lag: number, type: LinkType) => {\n const edgeKey = `${predecessorId}|${succId}|${type}`;\n if (seenEdges.has(edgeKey)) return;\n seenEdges.add(edgeKey);\n\n const outEdges = succByPred.get(predecessorId) ?? [];\n outEdges.push({ succId, lag, type });\n succByPred.set(predecessorId, outEdges);\n\n const inEdges = predBySucc.get(succId) ?? [];\n inEdges.push({ predId: predecessorId, lag, type });\n predBySucc.set(succId, inEdges);\n };\n\n for (const succ of leafTasks) {\n for (const dep of succ.dependencies ?? []) {\n const lag = getDependencyLag(dep);\n\n // Predecessor is a leaf: direct edge.\n if (leafIds.has(dep.taskId)) {\n addEdge(dep.taskId, succ.id, lag, dep.type);\n continue;\n }\n\n // Predecessor is a parent/group: expand to every leaf descendant.\n // The successor's own leaf (self-loop) is skipped.\n const descendants = leafIdsByAncestor.get(dep.taskId);\n if (!descendants || descendants.size === 0) continue;\n for (const leafId of descendants) {\n if (leafId === succ.id) continue;\n addEdge(leafId, succ.id, lag, dep.type);\n }\n }\n }\n\n // Topological order (Kahn). Vertices trapped in cycles never enter the order\n // (indegree never drops to 0) and are therefore excluded from criticality.\n const indegree = new Map<string, number>();\n for (const leaf of leafTasks) indegree.set(leaf.id, 0);\n for (const edges of succByPred.values()) {\n for (const { succId } of edges) {\n indegree.set(succId, (indegree.get(succId) ?? 0) + 1);\n }\n }\n\n const order: string[] = [];\n const enqueued = new Set<string>();\n const queue = leafTasks\n .filter((leaf) => (indegree.get(leaf.id) ?? 0) === 0)\n .map((leaf) => leaf.id);\n for (const id of queue) enqueued.add(id);\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n order.push(current);\n for (const { succId } of succByPred.get(current) ?? []) {\n const next = (indegree.get(succId) ?? 0) - 1;\n indegree.set(succId, next);\n if (next === 0 && !enqueued.has(succId)) {\n enqueued.add(succId);\n queue.push(succId);\n }\n }\n }\n\n const projectFinish = Math.max(\n 0,\n ...leafTasks.map((leaf) => (scheduledStart.get(leaf.id) ?? 0) + durationOf(leaf))\n );\n\n // Backward pass: late finish / late start.\n const LF = new Map<string, number>();\n const LS = new Map<string, number>();\n for (const leaf of leafTasks) LF.set(leaf.id, projectFinish);\n\n for (let i = order.length - 1; i >= 0; i--) {\n const id = order[i];\n const task = taskById.get(id)!;\n const durPred = durationOf(task);\n const outEdges = succByPred.get(id) ?? [];\n let lf = projectFinish;\n if (outEdges.length > 0) {\n const candidates = outEdges.map(({ succId, lag, type }) => {\n const succLs = LS.get(succId) ?? projectFinish;\n const durSucc = durationOf(taskById.get(succId)!);\n switch (type) {\n case 'FS': return succLs - lag;\n case 'SS': return succLs - lag + durPred;\n case 'FF': return succLs + durSucc - lag;\n case 'SF': return succLs + durSucc - lag + durPred;\n default: return projectFinish;\n }\n });\n lf = Math.min(projectFinish, ...candidates);\n }\n LF.set(id, lf);\n LS.set(id, lf - durPred);\n }\n\n const critical = new Set<string>();\n const ordered = new Set(order);\n for (const leaf of leafTasks) {\n // Vertices trapped in cycles never entered the topological order and are\n // never critical.\n if (!ordered.has(leaf.id)) continue;\n const hasGraphEdge =\n (succByPred.get(leaf.id)?.length ?? 0) > 0 ||\n (predBySucc.get(leaf.id)?.length ?? 0) > 0;\n // A task with no declared dependencies is a legitimate standalone\n // project task and may determine the project finish. If it declares\n // dependencies but none resolved to a valid graph edge (for example a\n // self-reference through its own parent), it is not a schedulable path.\n if (!hasGraphEdge && (leaf.dependencies?.length ?? 0) > 0) continue;\n const es = scheduledStart.get(leaf.id) ?? 0;\n const ls = LS.get(leaf.id) ?? 0;\n if (ls - es <= 0) critical.add(leaf.id);\n }\n\n return critical;\n}\n\n/**\n * Extend criticality from leaf ids upward through the parent chain.\n * A parent is critical when any of its descendants is critical.\n */\nexport function extendCriticalIdsToParents(\n criticalLeafIds: Set<string>,\n tasks: ScheduleTask[]\n): Set<string> {\n const result = new Set(criticalLeafIds);\n const parentByChild = new Map<string, string>();\n for (const task of tasks) {\n if (task.parentId) parentByChild.set(task.id, task.parentId);\n }\n\n const stack = Array.from(criticalLeafIds);\n while (stack.length > 0) {\n const id = stack.pop()!;\n const parentId = parentByChild.get(id);\n if (parentId && !result.has(parentId)) {\n result.add(parentId);\n stack.push(parentId);\n }\n }\n\n return result;\n}\n","/**\n * High-level schedule command functions.\n * Moved from dependencyUtils.ts — verbatim implementations.\n * Zero React/DOM/date-fns imports.\n */\n\n// START_MODULE_CONTRACT\n// PURPOSE: Build task ranges and update dependency lags for interactive scheduling commands.\n// SCOPE: Range construction, incoming FS clamping, and lag recalculation.\n// DEPENDS: dateMath, dependencies, scheduling types\n// LINKS: M-SCHEDULING, fn-clampTaskRangeForIncomingFS, fn-recalculateIncomingLags\n// ROLE: RUNTIME\n// MAP_MODE: EXPORTS\n// END_MODULE_CONTRACT\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 computeLagFromDates,\n normalizePredecessorDates,\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' | 'type'>,\n proposedStart: Date,\n proposedEnd: Date,\n allTasks: Task[],\n businessDays: boolean = false,\n weekendPredicate?: (date: Date) => boolean,\n taskById?: Map<string, Task>\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 = taskById?.get(dep.taskId) ?? allTasks.find(candidate => candidate.id === dep.taskId);\n if (!predecessor) {\n continue;\n }\n\n const { predStart: predecessorStart, predEnd: predecessorEnd } = normalizePredecessorDates(predecessor, parseDateOnly);\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 task.type\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 taskById?: Map<string, Task>\n): NonNullable<Task['dependencies']> {\n if (!task.dependencies) return [];\n return task.dependencies.map(dep => {\n const predecessor = taskById?.get(dep.taskId) ?? allTasks.find(candidate => candidate.id === dep.taskId);\n if (!predecessor) {\n return { ...dep, lag: getDependencyLag(dep) };\n }\n\n const { predStart: predecessorStart, predEnd: predecessorEnd } = normalizePredecessorDates(\n predecessor,\n (d) => new Date(d instanceof Date ? d.getTime() : `${String(d).split('T')[0]}T00:00:00.000Z`)\n );\n const nextLag = computeLagFromDates(\n dep.type,\n predecessorStart,\n predecessorEnd,\n newStartDate,\n newEndDate,\n businessDays,\n weekendPredicate,\n task.type\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\n// START_MODULE_CONTRACT\n// PURPOSE: Propagate moved task dates through dependency and hierarchy graphs.\n// SCOPE: Dependency cascades, parent/child propagation, and business-day alignment.\n// DEPENDS: commands, dateMath, dependencies, scheduling types\n// LINKS: M-SCHEDULING, fn-cascadeByLinks, fn-universalCascade\n// ROLE: RUNTIME\n// MAP_MODE: EXPORTS\n// END_MODULE_CONTRACT\n\nimport type { Task, LinkType } from './types';\nimport {\n normalizeUTCDate,\n getTaskDuration,\n alignToWorkingDay,\n} from './dateMath';\nimport {\n calculateSuccessorDate,\n getDependencyLag,\n normalizeTaskDependencyLags,\n normalizePredecessorDates,\n} from './dependencies';\nimport {\n buildTaskRangeFromStart,\n buildTaskRangeFromEnd,\n moveTaskRange,\n} from './commands';\n\nfunction parseCascadeDateInput(date: string | Date): Date {\n if (date instanceof Date) {\n return normalizeUTCDate(date);\n }\n return normalizeUTCDate(new Date(`${date.split('T')[0]}T00:00:00.000Z`));\n}\n\nexport interface CascadeContext {\n childrenByParentId: Map<string, Task[]>;\n dependentsByPredecessorId: Map<string, Array<{ task: Task; dependencyIndex: number }>>;\n taskById: Map<string, Task>;\n}\n\nexport function createCascadeContext(allTasks: Task[]): CascadeContext {\n const childrenByParentId = new Map<string, Task[]>();\n const dependentsByPredecessorId = new Map<string, Array<{ task: Task; dependencyIndex: number }>>();\n const taskById = new Map<string, Task>();\n\n for (const task of allTasks) {\n taskById.set(task.id, task);\n\n if (task.parentId) {\n const children = childrenByParentId.get(task.parentId) ?? [];\n children.push(task);\n childrenByParentId.set(task.parentId, children);\n }\n\n if (!task.dependencies) continue;\n\n task.dependencies.forEach((dependency, dependencyIndex) => {\n const dependents = dependentsByPredecessorId.get(dependency.taskId) ?? [];\n dependents.push({ task, dependencyIndex });\n dependentsByPredecessorId.set(dependency.taskId, dependents);\n });\n }\n\n return { childrenByParentId, dependentsByPredecessorId, taskById };\n}\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 { dependentsByPredecessorId, taskById } = createCascadeContext(allTasks);\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 = dependentsByPredecessorId.get(current) ?? [];\n for (const { task } of successors) {\n if (!linkTypes.includes(task.dependencies?.find((dependency) => dependency.taskId === current)?.type ?? 'FS')) {\n continue;\n }\n const sid = task.id;\n if (!visited.has(sid)) {\n visited.add(sid);\n const successorTask = taskById.get(sid);\n if (successorTask) {\n chain.push(successorTask);\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 { childrenByParentId, dependentsByPredecessorId, taskById } = createCascadeContext(allTasks);\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 = childrenByParentId.get(currentId) ?? [];\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(normalizeTaskDependencyLags({\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 const dependents = dependentsByPredecessorId.get(currentId) ?? [];\n for (const { task, dependencyIndex } of dependents) {\n if (visited.has(task.id) || !task.dependencies || task.locked) continue;\n const dep = task.dependencies[dependencyIndex];\n if (!dep) 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 currentTask = taskById.get(currentId)!;\n const { predStart: normalizedPredStart, predEnd: normalizedPredEnd } = normalizePredecessorDates(\n {\n startDate: predStart,\n endDate: predEnd,\n type: currentTask.type,\n },\n parseCascadeDateInput\n );\n const constraintDate = calculateSuccessorDate(\n normalizedPredStart,\n normalizedPredEnd,\n dep.type,\n getDependencyLag(dep),\n false,\n undefined,\n task.type\n );\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(normalizeTaskDependencyLags({\n ...task,\n startDate: newSuccStart.toISOString().split('T')[0],\n endDate: newSuccEnd.toISOString().split('T')[0],\n }));\n queue.push(task.id);\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 { childrenByParentId, dependentsByPredecessorId } = createCascadeContext(allTasks);\n\n const directChildren = childrenByParentId.get(changedTaskId) ?? [];\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 = childrenByParentId.get(current.id) ?? [];\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 = dependentsByPredecessorId.get(current.id) ?? [];\n for (const { task: 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 context: CascadeContext = createCascadeContext(allTasks)\n): Task[] {\n const { childrenByParentId, dependentsByPredecessorId, taskById } = context;\n const normalizedMovedTask = normalizeTaskDependencyLags({\n ...movedTask,\n startDate: newStart.toISOString().split('T')[0],\n endDate: newEnd.toISOString().split('T')[0],\n });\n\n if (\n !movedTask.parentId &&\n !childrenByParentId.has(movedTask.id) &&\n !dependentsByPredecessorId.has(movedTask.id)\n ) {\n return [normalizedMovedTask];\n }\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, normalizedMovedTask);\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 = childrenByParentId.get(currentId) ?? [];\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, normalizeTaskDependencyLags({\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 // A parent move is an explicit root operation. Its requested range is the\n // authoritative move target and must not be overwritten by the derived\n // min/max wrapper rollup when its shifted children are processed.\n if (parentId && parentId !== movedTask.id) {\n const parent = taskById.get(parentId);\n if (parent && !parent.locked) {\n const siblings = childrenByParentId.get(parentId) ?? [];\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, normalizeTaskDependencyLags({\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 // A successor that was already shifted rigidly as a child (RULE 1) is part of\n // the same moving subtree — re-applying its dependency constraints here would\n // collapse the gaps/slack between descendants (e.g. a positive lag) and make\n // them drift out of the moved parent by that amount. Preserve internal offsets.\n const dependents = dependentsByPredecessorId.get(currentId) ?? [];\n for (const { task, dependencyIndex } of dependents) {\n if (task.locked || !task.dependencies) continue;\n if (childShifted.has(task.id)) continue;\n const dep = task.dependencies[dependencyIndex];\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 { predStart: normalizedPredStart, predEnd: normalizedPredEnd } = normalizePredecessorDates(\n {\n startDate: currStart,\n endDate: currEnd,\n type: currentOriginal.type,\n },\n parseCascadeDateInput\n );\n const constraintDate = calculateSuccessorDate(\n normalizedPredStart, normalizedPredEnd, dep.type, getDependencyLag(dep),\n businessDays, weekendPredicate, task.type\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, normalizeTaskDependencyLags({\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 * Hierarchy scheduling functions.\n * Moved from dependencyUtils.ts — verbatim implementations.\n * Zero React/DOM/date-fns imports.\n */\n\n// START_MODULE_CONTRACT\n// PURPOSE: Query task hierarchy and build parent/descendant progress updates.\n// SCOPE: Child/descendant lookup, parent date/progress rollups, and boundary progress batch updates.\n// DEPENDS: scheduling types\n// LINKS: M-SCHEDULE, fn-getAllDescendants, fn-cascadeTaskProgress\n// ROLE: RUNTIME\n// MAP_MODE: EXPORTS\n// END_MODULE_CONTRACT\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 * Propagate an explicit boundary progress value through a task subtree.\n *\n * Fractional parent progress is intentionally left untouched: without\n * knowing which child work was completed, there is no reliable distribution.\n * Returns the changed parent and descendants as one sparse update batch.\n */\nexport function cascadeTaskProgress(task: Task, tasks: Task[]): Task[] {\n const progress = task.progress;\n if (progress !== 0 && progress !== 100) {\n return [task];\n }\n\n const descendants = getAllDescendants(task.id, tasks);\n if (descendants.length === 0) {\n return [task];\n }\n\n return [\n { ...task, progress },\n ...descendants.map((descendant) => ({ ...descendant, progress })),\n ];\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 * Command-level scheduling API.\n * High-level functions that compose low-level scheduling primitives.\n * Zero React/DOM/date-fns imports.\n */\n\n// START_MODULE_CONTRACT\n// PURPOSE: Execute authoritative task and project schedule recalculations.\n// SCOPE: Move, resize, dependency recalculation, cascade, and full-project scheduling.\n// DEPENDS: commands, cascade, dateMath, dependencies, hierarchy, scheduling types\n// LINKS: M-SCHEDULING, fn-recalculateTaskFromDependencies, fn-recalculateProjectSchedule\n// ROLE: RUNTIME\n// MAP_MODE: EXPORTS\n// END_MODULE_CONTRACT\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, normalizePredecessorDates } 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 one boundary while keeping the opposite boundary fixed.\n *\n * The public scheduling-intent contract names the boundary that stays fixed:\n * anchor='start' keeps the start date and derives the end date.\n * anchor='end' keeps the end date and derives the start date.\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 === 'start') {\n // anchor='start': start stays fixed, newDate is the requested end.\n newRange = { start: originalStart, end: newDate };\n } else {\n // anchor='end': end stays fixed, newDate is the requested start.\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, predEnd } = normalizePredecessorDates(predecessor, parseDateOnly);\n const constraintDate = calculateSuccessorDate(\n predStart,\n predEnd,\n dep.type,\n getDependencyLag(dep),\n businessDays,\n weekendPredicate,\n task.type\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 { predStart: predecessorStart, predEnd: predecessorEnd } = normalizePredecessorDates(predecessor, parseDateOnly);\n const constraintDate = calculateSuccessorDate(\n predecessorStart,\n predecessorEnd,\n dep.type,\n getDependencyLag(dep),\n businessDays,\n weekendPredicate,\n currentTask.type\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","import type { Task } from './types';\nimport { normalizeUTCDate, getTaskDuration, alignToWorkingDay } from './dateMath';\nimport { buildTaskRangeFromStart } from './commands';\nimport { computeParentDates, isTaskParent } from './hierarchy';\nimport { recalculateProjectSchedule } from './execute';\n\n/**\n * Recalculate all task dates when switching between business/calendar day modes.\n *\n * Mode switch semantics are not a simple per-task move:\n * 1. Leaf tasks first preserve their current duration count while snapping to\n * the target calendar rules.\n * 2. Parent tasks roll up from children.\n * 3. The full dependency graph is then recalculated in the target mode so\n * successors obey the new FS/SS/FF/SF semantics (for example Fri -> Mon in\n * business mode, Fri -> Sat in calendar mode).\n */\nexport function reflowTasksOnModeSwitch(\n sourceTasks: Task[],\n toBusinessDays: boolean,\n weekendPredicate: (date: Date) => boolean\n): Task[] {\n let tasks: Task[] = sourceTasks.map(task => ({\n ...task,\n dependencies: task.dependencies?.map(dependency => ({ ...dependency })),\n }));\n\n const toISO = (date: Date) => date.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 // Measure the duration in the TARGET mode, not the source mode. When going\n // calendar -> business (off -> on) each task must keep its BUSINESS day\n // count; counting in calendar days instead inflates every task by the\n // weekend days inside it, which pushes a task chain's tail forward past its\n // FS successor and inverts the connector.\n const duration = getTaskDuration(task.startDate, task.endDate, toBusinessDays, weekendPredicate);\n\n const range = toBusinessDays\n ? buildTaskRangeFromStart(\n alignToWorkingDay(start, 1, weekendPredicate),\n duration,\n true,\n weekendPredicate\n )\n : buildTaskRangeFromStart(start, duration, false);\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 const rescheduled = recalculateProjectSchedule(tasks, {\n businessDays: toBusinessDays,\n weekendPredicate,\n });\n\n if (rescheduled.changedTasks.length === 0) {\n return tasks;\n }\n\n const updates = new Map(rescheduled.changedTasks.map((task): [string, Task] => [task.id, task]));\n return tasks.map(task => updates.get(task.id) ?? task);\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 * Subtree duration scaling — proportional compress/stretch of a parent's subtree.\n * Zero React/DOM/date-fns imports.\n *\n * Semantics (PRD: 2026-08-23-parent-subtree-duration-scaling):\n * - Parent tasks stay computed wrappers; only leaf durations change.\n * - One common factor k scales mutable ordinary leaf durations; explicit positive\n * lags are preserved while the target is reachable via durations alone.\n * - Further compression reduces positive internal lags down to getMinLag, then\n * virtual offsets of independent components down to the anchor.\n * - Immutable tasks (locked by default) are pinned to their original dates and\n * never change any scheduling field.\n * - Milestones keep startDate === endDate and only move in time.\n * - Exact overall range wins over local proportion: a correction pass adjusts\n * one project day at a time with a provable iteration bound derived from the\n * adjustable slack (never a wall-clock timeout).\n * - Unreachable compression applies the proven minimum span and returns a\n * TARGET_CLAMPED_TO_MINIMUM warning instead of a hard error.\n *\n * The solver runs in a \"solve space\" of project-day indices where index 0 is the\n * fixed anchor boundary (original parent start for anchor:'start', the mirrored\n * original parent end for anchor:'end'). Dependency math stays in Date space\n * using the existing calculateSuccessorDate/buildTaskRange primitives, so both\n * calendar and business-day modes reuse one scheduling code path.\n */\n\n// START_MODULE_CONTRACT\n// PURPOSE: Proportionally scale a parent task subtree to an exact target duration.\n// SCOPE: Input validation, working-context indexing, pure layout evaluator,\n// duration and flexible-gap solving, date materialization with bottom-up\n// parent rollup, external dependency policies, sparse atomic result.\n// DEPENDS: scheduling types, dateMath, dependencies, commands, cascade, validation\n// LINKS: M-SCHEDULE, fn-scaleTaskSubtreeDuration, PRD-2026-08-23-parent-subtree-duration-scaling\n// ROLE: RUNTIME\n// MAP_MODE: EXPORTS\n// END_MODULE_CONTRACT\n\nimport type { LinkType, Task, TaskDependency } from './types';\nimport {\n DAY_MS,\n getBusinessDayOffset,\n getTaskDuration,\n parseDateOnly,\n shiftBusinessDayOffset,\n} from './dateMath';\nimport {\n calculateSuccessorDate,\n computeLagFromDates,\n normalizePredecessorDates,\n} from './dependencies';\nimport { buildTaskRangeFromEnd, buildTaskRangeFromStart } from './commands';\nimport { universalCascade } from './cascade';\nimport { validateDependencies } from './validation';\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\n/** Which boundary of the selected parent stays fixed during scaling. */\nexport type ScaleTaskSubtreeAnchor = 'start' | 'end';\n\n/** How dependencies leaving the subtree are handled. */\nexport type ScaleTaskSubtreeExternalPolicy = 'subtree-only' | 'cascade-successors';\n\nexport interface ScaleTaskSubtreeOptions {\n /** Fixed boundary of the parent range. Default: 'start'. */\n anchor?: ScaleTaskSubtreeAnchor;\n /** Count durations in business days via weekendPredicate. Default: false. */\n businessDays?: boolean;\n /** Weekend predicate used in business-day mode. */\n weekendPredicate?: (date: Date) => boolean;\n /**\n * External dependency policy. 'subtree-only' keeps every external task fixed\n * and fails with EXTERNAL_DEPENDENCY_CONFLICT on outgoing violations;\n * 'cascade-successors' shifts transitive external successors with preserved\n * durations. Default: 'subtree-only'.\n */\n externalDependencyPolicy?: ScaleTaskSubtreeExternalPolicy;\n /** Minimum duration override for a leaf task. Default: 1 (0 for milestones). */\n getMinDuration?: (task: Task) => number;\n /**\n * Minimum lag override for an internal positive dependency lag.\n * Default: 0. Called once per edge with the original task objects.\n */\n getMinLag?: (dependency: TaskDependency, ownerTask: Task) => number;\n /** Immutability override. Default: task.locked === true. */\n isImmutable?: (task: Task) => boolean;\n}\n\n/** Machine-readable warning attached to a successful scaling result. */\nexport type ScaleTaskSubtreeWarning =\n | {\n code: 'TARGET_CLAMPED_TO_MINIMUM';\n requestedDuration: number;\n minimumDuration: number;\n };\n\nexport type ScaleTaskSubtreeErrorCode =\n | 'INVALID_TARGET_DURATION'\n | 'TASK_NOT_FOUND'\n | 'NOT_A_PARENT'\n | 'INVALID_HIERARCHY'\n | 'INVALID_DEPENDENCIES'\n | 'INVALID_DATES'\n | 'INVALID_MINIMUM'\n | 'EXTERNAL_DEPENDENCY_CONFLICT';\n\nexport type ScaleTaskSubtreeResult =\n | {\n ok: true;\n changedTasks: Task[];\n changedIds: string[];\n requestedDuration: number;\n appliedDuration: number;\n clamped: boolean;\n warnings: ScaleTaskSubtreeWarning[];\n }\n | {\n ok: false;\n code: ScaleTaskSubtreeErrorCode;\n changedTasks: [];\n changedIds: [];\n details?: string[];\n };\n\n// ---------------------------------------------------------------------------\n// Internal model\n// ---------------------------------------------------------------------------\n\ninterface ScalingLeaf {\n id: string;\n task: Task;\n snapshotIndex: number;\n depth: number;\n isMilestone: boolean;\n immutable: boolean;\n /** Solve-space index of the original start date. */\n startIdx: number;\n /** Solve-space index of the original end date. */\n endIdx: number;\n /** Inclusive duration in project days; a milestone always occupies 1 cell. */\n duration: number;\n minDuration: number;\n componentId: number;\n isRoot: boolean;\n}\n\ninterface ScalingEdge {\n /** `${ownerTaskId}#${dependencyIndex}` — maps 1:1 onto the owner's dep entry. */\n key: string;\n predLeafId: string;\n succLeafId: string;\n type: LinkType;\n originalLag: number;\n minLag: number;\n /** Lags owned by parent tasks, immutable owners, or non-positive lags never change. */\n adjustable: boolean;\n}\n\ninterface IncomingBound {\n leafId: string;\n type: LinkType;\n lag: number;\n /** External predecessor task (never changes). */\n predTask: Task;\n}\n\ninterface OutgoingRef {\n /** Internal task id (leaf, nested parent, or the selected parent). */\n fromId: string;\n /** External successor task (owns the dependency entry). */\n succTask: Task;\n type: LinkType;\n lag: number;\n}\n\ninterface ScalingContext {\n businessDays: boolean;\n weekendPredicate?: (date: Date) => boolean;\n mirrored: boolean;\n parentTask: Task;\n snapshot: Task[];\n /** Descendant ids of the selected parent (parent excluded). */\n subtreeIds: Set<string>;\n /** Children by parent id over the whole snapshot. */\n childrenByParentId: Map<string, Task[]>;\n leaves: ScalingLeaf[];\n leafById: Map<string, ScalingLeaf>;\n /** Nested parents inside the subtree, deepest first (selected parent excluded). */\n nestedParents: Array<{ task: Task; depth: number; snapshotIndex: number }>;\n edges: ScalingEdge[];\n inEdges: Map<string, ScalingEdge[]>;\n outEdges: Map<string, ScalingEdge[]>;\n boundsByLeaf: Map<string, IncomingBound[]>;\n outgoingRefs: OutgoingRef[];\n /** Per-component floor for root offsets from parent-level FS/SS incoming deps. */\n componentFloor: Map<number, number>;\n originalSpan: number;\n /** Solver iteration budget derived from adjustable slack, not wall-clock. */\n maxCorrectionSteps: number;\n /** Resolved immutability predicate for external successor checks. */\n isImmutable: (task: Task) => boolean;\n}\n\ninterface SolverState {\n durations: Map<string, number>;\n lags: Map<string, number>;\n offsets: Map<string, number>;\n}\n\ninterface LeafRange {\n start: Date;\n end: Date;\n}\n\ninterface Layout {\n dates: Map<string, LeafRange>;\n /** Anchor-side boundary of the content extent in solve space. */\n lo: number;\n /** Far-side boundary of the content extent in solve space. */\n hi: number;\n span: number;\n}\n\nfunction toIsoDate(date: Date): string {\n return date.toISOString().split('T')[0];\n}\n\nfunction isoOfTaskDate(date: string | Date): string {\n return toIsoDate(parseDateOnly(date));\n}\n\nfunction scaleFailure(\n code: ScaleTaskSubtreeErrorCode,\n details?: string[]\n): ScaleTaskSubtreeResult {\n return details && details.length > 0\n ? { ok: false, code, changedTasks: [], changedIds: [], details }\n : { ok: false, code, changedTasks: [], changedIds: [] };\n}\n\nfunction isFiniteInteger(value: unknown): value is number {\n return typeof value === 'number' && Number.isFinite(value) && Number.isInteger(value);\n}\n\nfunction dependencyLag(dep: TaskDependency): number {\n return Number.isFinite(dep.lag) ? dep.lag : 0;\n}\n\n// ---------------------------------------------------------------------------\n// Solve-space conversion (index <-> date)\n// ---------------------------------------------------------------------------\n\ninterface SolveSpace {\n mirrored: boolean;\n anchorDate: Date;\n businessDays: boolean;\n weekendPredicate?: (date: Date) => boolean;\n idxCache: Map<string, number>;\n idxOf(date: Date): number;\n dateOf(idx: number): Date;\n}\n\nfunction createSolveSpace(\n mirrored: boolean,\n anchorDate: Date,\n businessDays: boolean,\n weekendPredicate?: (date: Date) => boolean\n): SolveSpace {\n const space: SolveSpace = {\n mirrored,\n anchorDate,\n businessDays,\n weekendPredicate,\n idxCache: new Map(),\n idxOf(date: Date): number {\n const key = toIsoDate(date);\n const cached = space.idxCache.get(key);\n if (cached !== undefined) {\n return cached;\n }\n let idx: number;\n if (businessDays && weekendPredicate) {\n idx = mirrored\n ? getBusinessDayOffset(date, anchorDate, weekendPredicate)\n : getBusinessDayOffset(anchorDate, date, weekendPredicate);\n } else {\n const deltaMs = date.getTime() - anchorDate.getTime();\n idx = mirrored ? -Math.round(deltaMs / DAY_MS) : Math.round(deltaMs / DAY_MS);\n }\n space.idxCache.set(key, idx);\n return idx;\n },\n dateOf(idx: number): Date {\n if (businessDays && weekendPredicate) {\n return shiftBusinessDayOffset(anchorDate, mirrored ? -idx : idx, weekendPredicate);\n }\n const delta = mirrored ? -idx : idx;\n return new Date(anchorDate.getTime() + delta * DAY_MS);\n },\n };\n return space;\n}\n\n// ---------------------------------------------------------------------------\n// Phase 1: validation\n// ---------------------------------------------------------------------------\n\n// START_BLOCK_VALIDATE_SCALE_INPUT\n\nfunction validateScaleInput(\n parentId: string,\n targetDuration: number,\n snapshot: Task[],\n businessDays: boolean,\n weekendPredicate?: (date: Date) => boolean\n): { ok: true; parentTask: Task } | { ok: false; code: ScaleTaskSubtreeErrorCode; details: string[] } {\n // 10.1 Target: finite integer >= 1.\n if (!isFiniteInteger(targetDuration) || targetDuration < 1) {\n return { ok: false, code: 'INVALID_TARGET_DURATION', details: [`targetDuration=${String(targetDuration)}`] };\n }\n\n // 10.2 Hierarchy: unique ids, resolvable parentId refs, no self-parent, no cycles.\n const taskById = new Map<string, Task>();\n const duplicateIds: string[] = [];\n for (const task of snapshot) {\n if (taskById.has(task.id)) duplicateIds.push(task.id);\n taskById.set(task.id, task);\n }\n if (duplicateIds.length > 0) {\n return { ok: false, code: 'INVALID_HIERARCHY', details: [`duplicate task ids: ${duplicateIds.slice(0, 5).join(', ')}`] };\n }\n\n const parentTask = taskById.get(parentId);\n if (!parentTask) {\n return { ok: false, code: 'TASK_NOT_FOUND', details: [`parentId=${parentId}`] };\n }\n\n const hasChild = snapshot.some((task) => task.parentId === parentId);\n if (!hasChild) {\n return { ok: false, code: 'NOT_A_PARENT', details: [`task ${parentId} has no children`] };\n }\n\n const childrenByParentId = new Map<string, Task[]>();\n const hierarchyErrors: string[] = [];\n for (const task of snapshot) {\n if (!task.parentId) continue;\n if (task.parentId === task.id) {\n hierarchyErrors.push(`self-parent: ${task.id}`);\n continue;\n }\n if (!taskById.has(task.parentId)) {\n hierarchyErrors.push(`missing parent ${task.parentId} for ${task.id}`);\n continue;\n }\n const children = childrenByParentId.get(task.parentId) ?? [];\n children.push(task);\n childrenByParentId.set(task.parentId, children);\n }\n if (hierarchyErrors.length === 0) {\n // Cycle detection: iterative walk up the parent chain with a visited guard.\n const globallyVisited = new Set<string>();\n for (const task of snapshot) {\n if (globallyVisited.has(task.id)) continue;\n const chain = new Set<string>();\n let current: Task | undefined = task;\n while (current?.parentId) {\n if (chain.has(current.id)) {\n hierarchyErrors.push(`hierarchy cycle at ${current.id}`);\n break;\n }\n chain.add(current.id);\n globallyVisited.add(current.id);\n current = taskById.get(current.parentId);\n }\n }\n }\n if (hierarchyErrors.length > 0) {\n return { ok: false, code: 'INVALID_HIERARCHY', details: hierarchyErrors.slice(0, 5) };\n }\n\n // 10.3 Dates of participating tasks: parseable, end >= start, business alignment.\n const subtreeIds = collectSubtreeIds(parentId, childrenByParentId);\n const participating = new Set<string>(subtreeIds);\n participating.add(parentId);\n // External dependency neighbours participate through bounds and outgoing checks.\n for (const task of snapshot) {\n const isInternal = subtreeIds.has(task.id) || task.id === parentId;\n for (const dep of task.dependencies ?? []) {\n if (isInternal) participating.add(dep.taskId);\n if (subtreeIds.has(dep.taskId) || dep.taskId === parentId) participating.add(task.id);\n }\n }\n\n const dateErrors: string[] = [];\n for (const id of participating) {\n const task = taskById.get(id);\n if (!task) continue;\n const start = parseDateOnly(task.startDate);\n const end = parseDateOnly(task.endDate);\n if (!Number.isFinite(start.getTime()) || !Number.isFinite(end.getTime())) {\n dateErrors.push(`unparseable dates on ${id}`);\n continue;\n }\n if (end.getTime() < start.getTime()) {\n dateErrors.push(`endDate before startDate on ${id}`);\n continue;\n }\n if (!subtreeIds.has(id)) continue;\n if (task.type === 'milestone' && start.getTime() !== end.getTime()) {\n dateErrors.push(`milestone ${id} must have equal start and end dates`);\n continue;\n }\n if (businessDays && weekendPredicate && !childrenByParentId.has(task.id)) {\n // Leaf boundaries must align to working days in business-day mode.\n if (weekendPredicate(start) || weekendPredicate(end)) {\n dateErrors.push(`leaf ${id} boundary falls on a weekend in business-day mode`);\n }\n }\n }\n if (dateErrors.length > 0) {\n return { ok: false, code: 'INVALID_DATES', details: dateErrors.slice(0, 5) };\n }\n\n // 10.4 Dependencies: existing validator covers missing endpoints, hierarchy\n // links between ancestors/descendants, and cycles.\n const depValidation = validateDependencies(snapshot);\n if (!depValidation.isValid) {\n return {\n ok: false,\n code: 'INVALID_DEPENDENCIES',\n details: depValidation.errors.slice(0, 5).map((error) => `${error.type}: ${error.taskId}`),\n };\n }\n\n return { ok: true, parentTask };\n}\n\n// END_BLOCK_VALIDATE_SCALE_INPUT\n\nfunction collectSubtreeIds(\n parentId: string,\n childrenByParentId: Map<string, Task[]>\n): Set<string> {\n const subtreeIds = new Set<string>();\n const queue = [parentId];\n while (queue.length > 0) {\n const current = queue.shift()!;\n for (const child of childrenByParentId.get(current) ?? []) {\n if (subtreeIds.has(child.id)) continue;\n subtreeIds.add(child.id);\n queue.push(child.id);\n }\n }\n return subtreeIds;\n}\n\n// ---------------------------------------------------------------------------\n// Phase 2: working context\n// ---------------------------------------------------------------------------\n\n// START_BLOCK_BUILD_SCALE_CONTEXT\n\ntype ContextBuildResult =\n | { ok: true; context: ScalingContext; space: SolveSpace }\n | { ok: false; code: ScaleTaskSubtreeErrorCode; details: string[] };\n\n/** Sentinel leaf id for parent-level incoming FS/SS bounds. */\nconst PARENT_BOUND_KEY = '__parent_bound__';\n\nfunction buildScaleContext(\n parentTask: Task,\n snapshot: Task[],\n options: ScaleTaskSubtreeOptions\n): ContextBuildResult {\n const businessDays = options.businessDays ?? false;\n const weekendPredicate = options.weekendPredicate;\n const isImmutable = options.isImmutable ?? ((task: Task) => task.locked === true);\n\n const indexedSnapshot = snapshot.map((task, index) => ({ task, index }));\n const taskById = new Map(indexedSnapshot.map(({ task }) => [task.id, task]));\n const childrenByParentId = new Map<string, Task[]>();\n for (const task of snapshot) {\n if (!task.parentId) continue;\n const children = childrenByParentId.get(task.parentId) ?? [];\n children.push(task);\n childrenByParentId.set(task.parentId, children);\n }\n\n const subtreeIds = collectSubtreeIds(parentTask.id, childrenByParentId);\n\n // Depths inside the subtree (selected parent = 0).\n const depthById = new Map<string, number>([[parentTask.id, 0]]);\n const depthQueue = [parentTask.id];\n while (depthQueue.length > 0) {\n const current = depthQueue.shift()!;\n const depth = depthById.get(current) ?? 0;\n for (const child of childrenByParentId.get(current) ?? []) {\n depthById.set(child.id, depth + 1);\n depthQueue.push(child.id);\n }\n }\n\n const subtreeTasks = indexedSnapshot.filter(({ task }) => subtreeIds.has(task.id));\n const leavesRaw = subtreeTasks.filter(({ task }) => !childrenByParentId.has(task.id));\n const nestedParentsRaw = subtreeTasks.filter(\n ({ task }) => childrenByParentId.has(task.id) && task.id !== parentTask.id\n );\n\n // The original parent range is derived from leaves bottom-up, never from the\n // stored parent dates (10.3).\n const leafEntries = leavesRaw.map(({ task, index }) => {\n const start = parseDateOnly(task.startDate);\n const end = parseDateOnly(task.endDate);\n return { task, index, start, end };\n });\n const computedStart = new Date(Math.min(...leafEntries.map((entry) => entry.start.getTime())));\n const computedEnd = new Date(Math.max(...leafEntries.map((entry) => entry.end.getTime())));\n const mirrored = (options.anchor ?? 'start') === 'end';\n const anchorDate = mirrored ? computedEnd : computedStart;\n const space = createSolveSpace(mirrored, anchorDate, businessDays, weekendPredicate);\n\n let lo = Number.POSITIVE_INFINITY;\n let hi = Number.NEGATIVE_INFINITY;\n for (const entry of leafEntries) {\n lo = Math.min(lo, space.idxOf(entry.start), space.idxOf(entry.end));\n hi = Math.max(hi, space.idxOf(entry.start), space.idxOf(entry.end));\n }\n const originalSpan = Number.isFinite(lo) ? hi - lo + 1 : 1;\n\n // Cache immutability once; user callbacks always receive original objects.\n const immutableById = new Map<string, boolean>();\n for (const { task } of subtreeTasks) {\n immutableById.set(task.id, isImmutable(task) === true);\n }\n\n // Cache and validate duration minima once (10.5).\n const getMinDuration = options.getMinDuration;\n const minDurationErrors: string[] = [];\n const minDurationById = new Map<string, number>();\n for (const { task } of subtreeTasks) {\n if (childrenByParentId.has(task.id)) continue; // leaves only\n if (task.type === 'milestone') {\n minDurationById.set(task.id, 0);\n continue;\n }\n let min = 1;\n if (getMinDuration) {\n const requested = getMinDuration(task);\n if (!isFiniteInteger(requested) || requested < 0) {\n minDurationErrors.push(`getMinDuration(${task.id}) = ${String(requested)}`);\n continue;\n }\n min = Math.max(1, requested);\n }\n minDurationById.set(task.id, min);\n }\n if (minDurationErrors.length > 0) {\n return { ok: false, code: 'INVALID_MINIMUM', details: minDurationErrors.slice(0, 5) };\n }\n\n const leaves: ScalingLeaf[] = leafEntries.map(({ task, index, start, end }) => ({\n id: task.id,\n task,\n snapshotIndex: index,\n depth: depthById.get(task.id) ?? 1,\n isMilestone: task.type === 'milestone',\n immutable: immutableById.get(task.id) === true,\n startIdx: space.idxOf(start),\n endIdx: space.idxOf(end),\n duration: getTaskDuration(start, end, businessDays, weekendPredicate),\n minDuration: minDurationById.get(task.id) ?? 1,\n componentId: -1,\n isRoot: false,\n }));\n const leafById = new Map(leaves.map((leaf) => [leaf.id, leaf]));\n\n // Anchor leaves of each nested parent (for dependency endpoint expansion).\n const anchorLeafByParent = new Map<string, { earliestStartId: string; latestEndId: string }>();\n const nestedParents: ScalingContext['nestedParents'] = nestedParentsRaw\n .map(({ task, index }) => ({ task, snapshotIndex: index, depth: depthById.get(task.id) ?? 1 }))\n .sort((left, right) => right.depth - left.depth || left.snapshotIndex - right.snapshotIndex);\n for (const { task } of nestedParents) {\n let earliestStart: ScalingLeaf | null = null;\n let latestEnd: ScalingLeaf | null = null;\n for (const leaf of leaves) {\n if (!isDescendantOf(leaf.task, task.id, taskById)) continue;\n if (!earliestStart || leaf.startIdx < earliestStart.startIdx) earliestStart = leaf;\n if (!latestEnd || leaf.endIdx > latestEnd.endIdx) latestEnd = leaf;\n }\n if (earliestStart && latestEnd) {\n anchorLeafByParent.set(task.id, { earliestStartId: earliestStart.id, latestEndId: latestEnd.id });\n }\n }\n\n // Internal edges (leaf <-> leaf after parent expansion), incoming bounds and\n // outgoing refs. Lags and minima are snapshotted exactly once.\n const getMinLag = options.getMinLag;\n const edges: ScalingEdge[] = [];\n const boundsByLeaf = new Map<string, IncomingBound[]>();\n const outgoingRefs: OutgoingRef[] = [];\n const lagErrors: string[] = [];\n\n const pushEdge = (\n ownerTask: Task,\n dep: TaskDependency,\n depIndex: number,\n predLeafId: string,\n succLeafId: string\n ) => {\n const originalLag = dependencyLag(dep);\n const succLeaf = leafById.get(succLeafId);\n const adjustable =\n originalLag > 0 &&\n !!succLeaf &&\n !succLeaf.immutable &&\n !immutableById.get(ownerTask.id);\n let minLag = originalLag;\n if (adjustable) {\n // Default minimum for a positive lag is 0 (10.5).\n minLag = 0;\n if (getMinLag) {\n const requested = getMinLag(dep, ownerTask);\n if (!isFiniteInteger(requested) || requested < 0 || requested > originalLag) {\n lagErrors.push(`getMinLag(${ownerTask.id}#${depIndex}) = ${String(requested)}`);\n } else {\n minLag = requested;\n }\n }\n }\n edges.push({\n key: `${ownerTask.id}#${depIndex}`,\n predLeafId,\n succLeafId,\n type: dep.type,\n originalLag,\n minLag,\n adjustable,\n });\n };\n\n for (const { task } of subtreeTasks) {\n if (!task.dependencies) continue;\n task.dependencies.forEach((dep, depIndex) => {\n const predTask = taskById.get(dep.taskId);\n if (!predTask) return; // missing endpoints already failed validation\n const predInside = subtreeIds.has(predTask.id);\n const isOwnerLeaf = leafById.has(task.id);\n\n if (!predInside) {\n // External incoming dependency.\n if (isOwnerLeaf) {\n const bounds = boundsByLeaf.get(task.id) ?? [];\n bounds.push({ leafId: task.id, type: dep.type, lag: dependencyLag(dep), predTask });\n boundsByLeaf.set(task.id, bounds);\n } else if (task.id === parentTask.id) {\n // Parent-level incoming FS/SS deps become component floors (10.4);\n // FF/SF parent-level deps are validated after materialization.\n if (dep.type === 'FS' || dep.type === 'SS') {\n const bounds = boundsByLeaf.get(PARENT_BOUND_KEY) ?? [];\n bounds.push({ leafId: PARENT_BOUND_KEY, type: dep.type, lag: dependencyLag(dep), predTask });\n boundsByLeaf.set(PARENT_BOUND_KEY, bounds);\n }\n } else {\n // Nested-parent incoming deps constrain the parent's boundary leaves.\n const anchors = anchorLeafByParent.get(task.id);\n if (anchors) {\n const targetLeafId =\n dep.type === 'FS' || dep.type === 'SS' ? anchors.earliestStartId : anchors.latestEndId;\n const bounds = boundsByLeaf.get(targetLeafId) ?? [];\n bounds.push({ leafId: targetLeafId, type: dep.type, lag: dependencyLag(dep), predTask });\n boundsByLeaf.set(targetLeafId, bounds);\n }\n }\n return;\n }\n\n // Internal edge: expand parent endpoints to anchor leaves.\n let predLeafId: string | undefined;\n if (leafById.has(predTask.id)) {\n predLeafId = predTask.id;\n } else {\n const anchors = anchorLeafByParent.get(predTask.id);\n if (anchors) {\n predLeafId = dep.type === 'FS' || dep.type === 'FF' ? anchors.latestEndId : anchors.earliestStartId;\n }\n }\n let succLeafId: string | undefined;\n if (isOwnerLeaf) {\n succLeafId = task.id;\n } else {\n const anchors = anchorLeafByParent.get(task.id);\n if (anchors) {\n succLeafId = dep.type === 'FS' || dep.type === 'SS' ? anchors.earliestStartId : anchors.latestEndId;\n }\n }\n if (predLeafId && succLeafId && predLeafId !== succLeafId) {\n pushEdge(task, dep, depIndex, predLeafId, succLeafId);\n }\n });\n }\n\n if (lagErrors.length > 0) {\n return { ok: false, code: 'INVALID_MINIMUM', details: lagErrors.slice(0, 5) };\n }\n\n // Outgoing refs: external successors that depend on internal tasks.\n for (const task of snapshot) {\n if (subtreeIds.has(task.id) || task.id === parentTask.id) continue;\n if (!task.dependencies) continue;\n for (const dep of task.dependencies) {\n if (!subtreeIds.has(dep.taskId) && dep.taskId !== parentTask.id) continue;\n outgoingRefs.push({ fromId: dep.taskId, succTask: task, type: dep.type, lag: dependencyLag(dep) });\n }\n }\n\n const inEdges = new Map<string, ScalingEdge[]>();\n const outEdges = new Map<string, ScalingEdge[]>();\n for (const edge of edges) {\n const inList = inEdges.get(edge.succLeafId) ?? [];\n inList.push(edge);\n inEdges.set(edge.succLeafId, inList);\n const outList = outEdges.get(edge.predLeafId) ?? [];\n outList.push(edge);\n outEdges.set(edge.predLeafId, outList);\n }\n for (const leaf of leaves) {\n leaf.isRoot = (inEdges.get(leaf.id)?.length ?? 0) === 0;\n }\n\n // Connected components over internal edges (union-find, snapshot order).\n const componentRoot = new Map<string, string>(leaves.map((leaf) => [leaf.id, leaf.id]));\n const find = (id: string): string => {\n let root = componentRoot.get(id) ?? id;\n if (root === id) return root;\n root = find(root);\n componentRoot.set(id, root);\n return root;\n };\n const union = (a: string, b: string) => {\n const ra = find(a);\n const rb = find(b);\n if (ra !== rb) componentRoot.set(ra, rb);\n };\n for (const edge of edges) union(edge.predLeafId, edge.succLeafId);\n const componentIdByRoot = new Map<string, number>();\n let componentCount = 0;\n for (const leaf of leaves) {\n const root = find(leaf.id);\n if (!componentIdByRoot.has(root)) {\n componentIdByRoot.set(root, componentCount);\n componentCount++;\n }\n leaf.componentId = componentIdByRoot.get(root)!;\n }\n\n // Component floors from parent-level incoming FS/SS bounds.\n const componentFloor = new Map<number, number>();\n const parentBounds = boundsByLeaf.get(PARENT_BOUND_KEY) ?? [];\n for (const bound of parentBounds) {\n const { predStart, predEnd } = normalizePredecessorDates(bound.predTask, parseDateOnly);\n const boundDate = calculateSuccessorDate(\n predStart,\n predEnd,\n bound.type,\n bound.lag,\n businessDays,\n weekendPredicate\n );\n const boundIdx = space.idxOf(boundDate);\n for (const leaf of leaves) {\n if (!leaf.isRoot || leaf.immutable) continue;\n componentFloor.set(leaf.componentId, Math.max(componentFloor.get(leaf.componentId) ?? 0, boundIdx));\n }\n }\n boundsByLeaf.delete(PARENT_BOUND_KEY);\n\n // Iteration budget: total adjustable days (durations + lags + offsets) plus\n // the maximum possible growth — never a wall-clock timeout.\n let adjustableTotal = 0;\n for (const leaf of leaves) {\n if (leaf.immutable || leaf.isMilestone) continue;\n adjustableTotal += Math.max(0, leaf.duration - leaf.minDuration);\n }\n for (const edge of edges) {\n if (edge.adjustable && edge.originalLag > edge.minLag) {\n adjustableTotal += edge.originalLag - edge.minLag;\n }\n }\n for (const leaf of leaves) {\n if (leaf.isRoot && !leaf.immutable) adjustableTotal += Math.max(0, leaf.startIdx);\n }\n const maxCorrectionSteps = 2 * (adjustableTotal + originalSpan) + targetBudgetGuard(originalSpan) + 64;\n\n const context: ScalingContext = {\n businessDays,\n weekendPredicate,\n mirrored,\n parentTask,\n snapshot,\n subtreeIds,\n childrenByParentId,\n leaves,\n leafById,\n nestedParents,\n edges,\n inEdges,\n outEdges,\n boundsByLeaf,\n outgoingRefs,\n componentFloor,\n originalSpan,\n maxCorrectionSteps,\n isImmutable,\n };\n\n return { ok: true, context, space };\n}\n\nfunction targetBudgetGuard(originalSpan: number): number {\n return Math.max(1, originalSpan) * 2;\n}\n\nfunction isDescendantOf(task: Task, ancestorId: string, taskById: Map<string, Task>): boolean {\n const visited = new Set<string>();\n let currentId = task.parentId;\n while (currentId) {\n if (currentId === ancestorId) return true;\n if (visited.has(currentId)) return false;\n visited.add(currentId);\n currentId = taskById.get(currentId)?.parentId;\n }\n return false;\n}\n\n// END_BLOCK_BUILD_SCALE_CONTEXT\n\n// ---------------------------------------------------------------------------\n// Phase 3: layout evaluator (pure)\n// ---------------------------------------------------------------------------\n\nfunction topoOrderLeaves(ctx: ScalingContext, componentLeaves: ScalingLeaf[]): ScalingLeaf[] {\n const byId = new Map(componentLeaves.map((leaf) => [leaf.id, leaf]));\n const indegree = new Map<string, number>(\n componentLeaves.map((leaf) => [leaf.id, 0])\n );\n for (const leaf of componentLeaves) {\n for (const edge of ctx.inEdges.get(leaf.id) ?? []) {\n if (byId.has(edge.predLeafId)) {\n indegree.set(leaf.id, (indegree.get(leaf.id) ?? 0) + 1);\n }\n }\n }\n const ready = componentLeaves\n .filter((leaf) => (indegree.get(leaf.id) ?? 0) === 0)\n .sort((left, right) => left.snapshotIndex - right.snapshotIndex);\n const ordered: ScalingLeaf[] = [];\n const emitted = new Set<string>();\n while (ready.length > 0) {\n const current = ready.shift()!;\n ordered.push(current);\n emitted.add(current.id);\n for (const edge of ctx.outEdges.get(current.id) ?? []) {\n if (!byId.has(edge.succLeafId) || emitted.has(edge.succLeafId)) continue;\n const next = (indegree.get(edge.succLeafId) ?? 0) - 1;\n indegree.set(edge.succLeafId, next);\n if (next === 0) {\n ready.push(byId.get(edge.succLeafId)!);\n ready.sort((left, right) => left.snapshotIndex - right.snapshotIndex);\n }\n }\n }\n // Cycle-free input is validated upfront; append leftovers defensively.\n for (const leaf of componentLeaves) {\n if (!emitted.has(leaf.id)) ordered.push(leaf);\n }\n return ordered;\n}\n\nfunction evaluateLayout(ctx: ScalingContext, space: SolveSpace, state: SolverState): Layout {\n const { businessDays, weekendPredicate } = ctx;\n const dates = new Map<string, LeafRange>();\n\n // Immutable leaves are pinned to their original dates.\n for (const leaf of ctx.leaves) {\n if (leaf.immutable) {\n dates.set(leaf.id, {\n start: parseDateOnly(leaf.task.startDate),\n end: parseDateOnly(leaf.task.endDate),\n });\n }\n }\n\n // Components in deterministic order (first member snapshot index).\n const componentOrder: number[] = [];\n const componentLeaves = new Map<number, ScalingLeaf[]>();\n for (const leaf of ctx.leaves) {\n const list = componentLeaves.get(leaf.componentId) ?? [];\n list.push(leaf);\n componentLeaves.set(leaf.componentId, list);\n if (list.length === 1) componentOrder.push(leaf.componentId);\n }\n\n for (const componentId of componentOrder) {\n const members = componentLeaves.get(componentId) ?? [];\n const order = topoOrderLeaves(ctx, members);\n for (const leaf of order) {\n if (dates.has(leaf.id)) continue; // pinned\n const duration = state.durations.get(leaf.id) ?? leaf.duration;\n let range: LeafRange | null = null;\n\n const incoming = ctx.inEdges.get(leaf.id) ?? [];\n if (incoming.length === 0) {\n const floor = ctx.componentFloor.get(leaf.componentId) ?? 0;\n const offset = Math.max(floor, state.offsets.get(leaf.id) ?? leaf.startIdx);\n range = buildTaskRangeFromStart(space.dateOf(offset), duration, businessDays, weekendPredicate);\n } else {\n for (const edge of incoming) {\n const predDates = dates.get(edge.predLeafId);\n if (!predDates) continue;\n const predLeaf = ctx.leafById.get(edge.predLeafId);\n const { predStart, predEnd } = normalizePredecessorDates(\n {\n startDate: predDates.start,\n endDate: predDates.end,\n type: predLeaf?.isMilestone ? ('milestone' as const) : ('task' as const),\n },\n parseDateOnly\n );\n const lag = state.lags.get(edge.key) ?? edge.originalLag;\n const constraint = calculateSuccessorDate(\n predStart,\n predEnd,\n edge.type,\n lag,\n businessDays,\n weekendPredicate,\n leaf.isMilestone ? 'milestone' : undefined\n );\n const candidate =\n edge.type === 'FS' || edge.type === 'SS'\n ? buildTaskRangeFromStart(constraint, duration, businessDays, weekendPredicate)\n : buildTaskRangeFromEnd(constraint, duration, businessDays, weekendPredicate);\n if (\n !range ||\n candidate.start.getTime() > range.start.getTime() ||\n (candidate.start.getTime() === range.start.getTime() &&\n candidate.end.getTime() > range.end.getTime())\n ) {\n range = candidate;\n }\n }\n }\n if (!range) {\n range = buildTaskRangeFromStart(space.dateOf(leaf.startIdx), duration, businessDays, weekendPredicate);\n }\n\n // Incoming external bounds: immovable lower constraints in time.\n for (const bound of ctx.boundsByLeaf.get(leaf.id) ?? []) {\n const { predStart, predEnd } = normalizePredecessorDates(bound.predTask, parseDateOnly);\n const boundDate = calculateSuccessorDate(\n predStart,\n predEnd,\n bound.type,\n bound.lag,\n businessDays,\n weekendPredicate,\n leaf.isMilestone ? 'milestone' : undefined\n );\n if ((bound.type === 'FS' || bound.type === 'SS') && range.start.getTime() < boundDate.getTime()) {\n range = buildTaskRangeFromStart(boundDate, duration, businessDays, weekendPredicate);\n } else if ((bound.type === 'FF' || bound.type === 'SF') && range.end.getTime() < boundDate.getTime()) {\n range = buildTaskRangeFromEnd(boundDate, duration, businessDays, weekendPredicate);\n }\n }\n\n // Reverse bounds: mutable predecessors must not overlap pinned successors.\n for (const edge of ctx.outEdges.get(leaf.id) ?? []) {\n const succLeaf = ctx.leafById.get(edge.succLeafId);\n if (!succLeaf || !succLeaf.immutable) continue;\n const succDates = dates.get(succLeaf.id);\n if (!succDates) continue;\n const lag = state.lags.get(edge.key) ?? edge.originalLag;\n range = applyReverseBound(\n range,\n edge.type,\n lag,\n succDates,\n succLeaf.isMilestone,\n duration,\n businessDays,\n weekendPredicate\n );\n }\n\n // Anchor-side clamp: content never crosses the fixed boundary.\n range = clampToAnchor(range, space, duration, businessDays, weekendPredicate);\n\n dates.set(leaf.id, range);\n }\n }\n\n let lo = Number.POSITIVE_INFINITY;\n let hi = Number.NEGATIVE_INFINITY;\n for (const leaf of ctx.leaves) {\n const range = dates.get(leaf.id);\n if (!range) continue;\n const startIdx = space.idxOf(range.start);\n const endIdx = space.idxOf(range.end);\n lo = Math.min(lo, startIdx, endIdx);\n hi = Math.max(hi, startIdx, endIdx);\n }\n if (!Number.isFinite(lo) || !Number.isFinite(hi)) {\n return { dates, lo: 0, hi: 0, span: 1 };\n }\n return { dates, lo, hi, span: hi - lo + 1 };\n}\n\nfunction applyReverseBound(\n range: LeafRange,\n type: LinkType,\n lag: number,\n succDates: LeafRange,\n succIsMilestone: boolean,\n duration: number,\n businessDays: boolean,\n weekendPredicate?: (date: Date) => boolean\n): LeafRange {\n const shiftBack = (date: Date, days: number): Date =>\n businessDays && weekendPredicate\n ? shiftBusinessDayOffset(date, -days, weekendPredicate)\n : new Date(date.getTime() - days * DAY_MS);\n\n switch (type) {\n case 'FS': {\n const allowedEnd = shiftBack(succDates.start, lag + (succIsMilestone ? 0 : 1));\n return range.end.getTime() > allowedEnd.getTime()\n ? buildTaskRangeFromEnd(allowedEnd, duration, businessDays, weekendPredicate)\n : range;\n }\n case 'SS': {\n const allowedStart = shiftBack(succDates.start, lag);\n return range.start.getTime() > allowedStart.getTime()\n ? buildTaskRangeFromStart(allowedStart, duration, businessDays, weekendPredicate)\n : range;\n }\n case 'FF': {\n const allowedEnd = shiftBack(succDates.end, lag);\n return range.end.getTime() > allowedEnd.getTime()\n ? buildTaskRangeFromEnd(allowedEnd, duration, businessDays, weekendPredicate)\n : range;\n }\n case 'SF': {\n const allowedStart = shiftBack(succDates.end, lag - 1);\n return range.start.getTime() > allowedStart.getTime()\n ? buildTaskRangeFromStart(allowedStart, duration, businessDays, weekendPredicate)\n : range;\n }\n }\n}\n\nfunction clampToAnchor(\n range: LeafRange,\n space: SolveSpace,\n duration: number,\n businessDays: boolean,\n weekendPredicate?: (date: Date) => boolean\n): LeafRange {\n if (!space.mirrored) {\n // Start-anchored: content never starts before the original parent start.\n if (space.idxOf(range.start) < 0) {\n return buildTaskRangeFromStart(space.anchorDate, duration, businessDays, weekendPredicate);\n }\n } else if (space.idxOf(range.end) < 0) {\n // End-anchored: content never ends after the original parent end.\n return buildTaskRangeFromEnd(space.anchorDate, duration, businessDays, weekendPredicate);\n }\n return range;\n}\n\n// ---------------------------------------------------------------------------\n// Phase 4: solving (stage A durations, correction, stage B flexible gaps)\n// ---------------------------------------------------------------------------\n\n// START_BLOCK_SOLVE_DURATIONS\n\nfunction allocateDurations(ctx: ScalingContext, target: number): Map<string, number> {\n const durations = new Map<string, number>();\n const ratio = target / Math.max(1, ctx.originalSpan);\n\n for (const leaf of ctx.leaves) {\n if (leaf.immutable || leaf.isMilestone) {\n durations.set(leaf.id, leaf.duration);\n }\n }\n\n const ideals: Array<{ leaf: ScalingLeaf; ideal: number }> = ctx.leaves\n .filter((leaf) => !leaf.immutable && !leaf.isMilestone)\n .map((leaf) => ({ leaf, ideal: Math.max(leaf.minDuration, leaf.duration * ratio) }));\n\n const minTotal = ideals.reduce((sum, { leaf }) => sum + leaf.minDuration, 0);\n const idealTotal = ideals.reduce((sum, { ideal }) => sum + ideal, 0);\n const total = Math.max(minTotal, Math.round(idealTotal));\n\n const floors = new Map<string, number>();\n let floorTotal = 0;\n for (const { leaf, ideal } of ideals) {\n const floor = Math.max(leaf.minDuration, Math.floor(ideal));\n floors.set(leaf.id, floor);\n floorTotal += floor;\n }\n\n // Largest remainder with deterministic tie-break: larger fraction first,\n // then earlier original start, then id.\n let remaining = Math.max(0, total - floorTotal);\n const byFraction = [...ideals].sort((left, right) => {\n const fracLeft = left.ideal - (floors.get(left.leaf.id) ?? 0);\n const fracRight = right.ideal - (floors.get(right.leaf.id) ?? 0);\n if (fracLeft !== fracRight) return fracRight - fracLeft;\n const timeLeft = isoOfTaskDate(left.leaf.task.startDate);\n const timeRight = isoOfTaskDate(right.leaf.task.startDate);\n if (timeLeft !== timeRight) return timeLeft < timeRight ? -1 : 1;\n return left.leaf.id < right.leaf.id ? -1 : 1;\n });\n for (const { leaf } of byFraction) {\n if (remaining <= 0) break;\n floors.set(leaf.id, (floors.get(leaf.id) ?? 0) + 1);\n remaining -= 1;\n }\n\n for (const { leaf } of ideals) {\n durations.set(leaf.id, floors.get(leaf.id) ?? leaf.duration);\n }\n return durations;\n}\n\n// END_BLOCK_SOLVE_DURATIONS\n\n// START_BLOCK_SOLVE_FLEXIBLE_GAPS\n\ninterface SolveOutcome {\n state: SolverState;\n layout: Layout;\n appliedSpan: number;\n clamped: boolean;\n}\n\nfunction solveScale(ctx: ScalingContext, space: SolveSpace, target: number): SolveOutcome {\n const state: SolverState = {\n durations: allocateDurations(ctx, target),\n lags: new Map(ctx.edges.map((edge) => [edge.key, edge.originalLag])),\n offsets: new Map(\n ctx.leaves\n .filter((leaf) => leaf.isRoot && !leaf.immutable)\n .map((leaf) => {\n const floor = ctx.componentFloor.get(leaf.componentId) ?? 0;\n const scaled = Math.round((leaf.startIdx * target) / Math.max(1, ctx.originalSpan));\n return [leaf.id, Math.max(floor, scaled)] as const;\n })\n ),\n };\n\n let layout = evaluateLayout(ctx, space, state);\n let exhausted = false;\n let steps = 0;\n\n while (layout.span !== target && steps < ctx.maxCorrectionSteps) {\n steps++;\n if (layout.span > target) {\n if (tryFirstImprovementReduce(ctx, space, state, layout)) {\n layout = evaluateLayout(ctx, space, state);\n continue;\n }\n if (exhausted) break;\n // Stage B exhaustion: durations to minima, positive lags to minima,\n // virtual offsets to their floors — the proven minimum layout.\n exhausted = true;\n exhaustFlexibleGaps(ctx, state);\n layout = evaluateLayout(ctx, space, state);\n continue;\n }\n if (tryGrow(ctx, space, state, layout, target)) {\n layout = evaluateLayout(ctx, space, state);\n continue;\n }\n break;\n }\n\n // Align the anchor-side boundary (index 0) when the layout allows it.\n layout = alignAnchorBoundary(ctx, space, state, layout);\n\n return {\n state,\n layout,\n appliedSpan: layout.span,\n clamped: layout.span > target,\n };\n}\n\nfunction farBoundaryKey(\n leaf: ScalingLeaf,\n dates: Map<string, LeafRange>,\n space: SolveSpace\n): number {\n const range = dates.get(leaf.id);\n if (!range) return Math.max(leaf.startIdx, leaf.endIdx);\n return Math.max(space.idxOf(range.start), space.idxOf(range.end));\n}\n\nfunction tryFirstImprovementReduce(\n ctx: ScalingContext,\n space: SolveSpace,\n state: SolverState,\n layout: Layout\n): boolean {\n // 1. Durations of boundary-defining mutable ordinary leaves.\n const durationCandidates = ctx.leaves\n .filter(\n (leaf) =>\n !leaf.immutable &&\n !leaf.isMilestone &&\n (state.durations.get(leaf.id) ?? leaf.duration) > leaf.minDuration\n )\n .sort(\n (left, right) =>\n farBoundaryKey(right, layout.dates, space) - farBoundaryKey(left, layout.dates, space) ||\n left.snapshotIndex - right.snapshotIndex\n );\n for (const leaf of durationCandidates) {\n const current = state.durations.get(leaf.id) ?? leaf.duration;\n state.durations.set(leaf.id, current - 1);\n const next = evaluateLayout(ctx, space, state);\n if (next.span < layout.span) return true;\n state.durations.set(leaf.id, current);\n }\n\n // 2. Positive internal explicit lags (durations are exhausted at this point).\n const lagCandidates = ctx.edges\n .filter((edge) => edge.adjustable && (state.lags.get(edge.key) ?? edge.originalLag) > edge.minLag)\n .sort((left, right) => {\n const succLeft = ctx.leafById.get(left.succLeafId)?.snapshotIndex ?? 0;\n const succRight = ctx.leafById.get(right.succLeafId)?.snapshotIndex ?? 0;\n if (succLeft !== succRight) return succLeft - succRight;\n return left.key < right.key ? -1 : 1;\n });\n for (const edge of lagCandidates) {\n const current = state.lags.get(edge.key) ?? edge.originalLag;\n state.lags.set(edge.key, current - 1);\n const next = evaluateLayout(ctx, space, state);\n if (next.span < layout.span) return true;\n state.lags.set(edge.key, current);\n }\n\n // 3. Virtual offsets of independent component roots.\n const offsetCandidates = ctx.leaves\n .filter((leaf) => leaf.isRoot && !leaf.immutable)\n .map((leaf) => ({ leaf, offset: state.offsets.get(leaf.id) ?? leaf.startIdx }))\n .filter(({ leaf, offset }) => offset > (ctx.componentFloor.get(leaf.componentId) ?? 0))\n .sort(\n (left, right) =>\n right.offset - left.offset || left.leaf.snapshotIndex - right.leaf.snapshotIndex\n );\n for (const { leaf, offset } of offsetCandidates) {\n state.offsets.set(leaf.id, offset - 1);\n const next = evaluateLayout(ctx, space, state);\n if (next.span < layout.span) return true;\n state.offsets.set(leaf.id, offset);\n }\n\n return false;\n}\n\nfunction exhaustFlexibleGaps(ctx: ScalingContext, state: SolverState): void {\n for (const leaf of ctx.leaves) {\n if (leaf.immutable || leaf.isMilestone) continue;\n state.durations.set(leaf.id, leaf.minDuration);\n }\n for (const edge of ctx.edges) {\n if (edge.adjustable) {\n state.lags.set(edge.key, edge.minLag);\n }\n }\n for (const leaf of ctx.leaves) {\n if (!leaf.isRoot || leaf.immutable) continue;\n state.offsets.set(leaf.id, ctx.componentFloor.get(leaf.componentId) ?? 0);\n }\n}\n\nfunction tryGrow(\n ctx: ScalingContext,\n space: SolveSpace,\n state: SolverState,\n layout: Layout,\n target: number\n): boolean {\n const growthCandidates = ctx.leaves\n .filter((leaf) => !leaf.immutable && !leaf.isMilestone)\n .sort(\n (left, right) =>\n farBoundaryKey(right, layout.dates, space) - farBoundaryKey(left, layout.dates, space) ||\n left.snapshotIndex - right.snapshotIndex\n );\n for (const leaf of growthCandidates) {\n const current = state.durations.get(leaf.id) ?? leaf.duration;\n state.durations.set(leaf.id, current + 1);\n const next = evaluateLayout(ctx, space, state);\n if (next.span > layout.span && next.span <= target) return true;\n state.durations.set(leaf.id, current);\n }\n\n // Grow offsets of the farthest independent roots (e.g. milestone-only subtrees).\n const offsetCandidates = ctx.leaves\n .filter((leaf) => leaf.isRoot && !leaf.immutable)\n .map((leaf) => ({ leaf, offset: state.offsets.get(leaf.id) ?? leaf.startIdx }))\n .sort(\n (left, right) =>\n right.offset - left.offset || left.leaf.snapshotIndex - right.leaf.snapshotIndex\n );\n for (const { leaf, offset } of offsetCandidates) {\n state.offsets.set(leaf.id, offset + 1);\n const next = evaluateLayout(ctx, space, state);\n if (next.span > layout.span && next.span <= target) return true;\n state.offsets.set(leaf.id, offset);\n }\n return false;\n}\n\nfunction alignAnchorBoundary(\n ctx: ScalingContext,\n space: SolveSpace,\n state: SolverState,\n layout: Layout\n): Layout {\n if (layout.lo === 0) return layout;\n if (ctx.leaves.some((leaf) => leaf.immutable)) return layout;\n if (ctx.boundsByLeaf.size > 0) return layout;\n if (ctx.componentFloor.size > 0) return layout;\n\n const roots = ctx.leaves.filter((leaf) => leaf.isRoot && !leaf.immutable);\n if (roots.length === 0) return layout;\n const minOffset = Math.min(\n ...roots.map((leaf) => state.offsets.get(leaf.id) ?? leaf.startIdx)\n );\n if (minOffset <= 0) return layout;\n const shift = Math.min(layout.lo, minOffset);\n if (shift <= 0) return layout;\n\n const backup = new Map(state.offsets);\n for (const leaf of roots) {\n state.offsets.set(leaf.id, (state.offsets.get(leaf.id) ?? leaf.startIdx) - shift);\n }\n const next = evaluateLayout(ctx, space, state);\n if (next.span === layout.span && next.lo < layout.lo) {\n return next;\n }\n state.offsets.clear();\n for (const [key, value] of backup) state.offsets.set(key, value);\n return layout;\n}\n\n// END_BLOCK_SOLVE_FLEXIBLE_GAPS\n\n// ---------------------------------------------------------------------------\n// Phase 5: materialization + external policies + sparse result\n// ---------------------------------------------------------------------------\n\n// START_BLOCK_MATERIALIZE_SCALE_RESULT\n\n/**\n * Build the leaf's next dependency list: internal lags take the solved values,\n * external incoming lags are recalculated from the final dates. Returns null\n * when nothing changed.\n */\nfunction buildLeafDependencies(\n leaf: ScalingLeaf,\n range: LeafRange,\n finalDates: Map<string, LeafRange>,\n taskById: Map<string, Task>,\n state: SolverState,\n ctx: ScalingContext,\n space: SolveSpace\n): TaskDependency[] | null {\n const deps = leaf.task.dependencies;\n if (!deps || deps.length === 0) return null;\n let changed = false;\n const nextDeps = deps.map((dep, depIndex) => {\n const key = `${leaf.id}#${depIndex}`;\n const solvedLag = state.lags.get(key);\n if (solvedLag !== undefined && solvedLag !== dependencyLag(dep)) {\n changed = true;\n return { ...dep, lag: solvedLag };\n }\n const predTask = taskById.get(dep.taskId);\n if (!predTask) return { ...dep, lag: dependencyLag(dep) };\n if (ctx.subtreeIds.has(predTask.id)) {\n // Internal edge without a solver entry (e.g. collapsed expansion): keep it.\n return { ...dep, lag: dependencyLag(dep) };\n }\n // External predecessor: reflect the actual final gap.\n const predRange = finalDates.get(predTask.id);\n const { predStart, predEnd } = normalizePredecessorDates(\n {\n startDate: predRange ? predRange.start : parseDateOnly(predTask.startDate),\n endDate: predRange ? predRange.end : parseDateOnly(predTask.endDate),\n type: predTask.type,\n },\n parseDateOnly\n );\n const lag = computeLagFromDates(\n dep.type,\n predStart,\n predEnd,\n range.start,\n range.end,\n ctx.businessDays,\n ctx.weekendPredicate,\n leaf.isMilestone ? 'milestone' : undefined\n );\n if (lag !== dependencyLag(dep)) changed = true;\n return { ...dep, lag };\n });\n void space;\n return changed ? nextDeps : null;\n}\n\nfunction buildFinalTasks(\n ctx: ScalingContext,\n state: SolverState,\n layout: Layout,\n space: SolveSpace\n): Map<string, Task> {\n const taskById = new Map(ctx.snapshot.map((task) => [task.id, task]));\n const finalTasks = new Map<string, Task>();\n\n // Leaves: new dates + updated dependency lags for mutable leaves.\n for (const leaf of ctx.leaves) {\n if (leaf.immutable) continue;\n const range = layout.dates.get(leaf.id);\n if (!range) continue;\n const newStart = toIsoDate(range.start);\n const newEnd = toIsoDate(range.end);\n const startChanged = newStart !== isoOfTaskDate(leaf.task.startDate);\n const endChanged = newEnd !== isoOfTaskDate(leaf.task.endDate);\n const nextDeps = buildLeafDependencies(leaf, range, layout.dates, taskById, state, ctx, space);\n if (!startChanged && !endChanged && !nextDeps) continue;\n finalTasks.set(leaf.id, {\n ...leaf.task,\n startDate: newStart,\n endDate: newEnd,\n ...(nextDeps ? { dependencies: nextDeps } : {}),\n });\n }\n\n // Nested parents, deepest first: roll up from direct children.\n for (const { task } of ctx.nestedParents) {\n const children = ctx.childrenByParentId.get(task.id) ?? [];\n let minStart: Date | null = null;\n let maxEnd: Date | null = null;\n for (const child of children) {\n const childFinal = finalTasks.get(child.id);\n const start = parseDateOnly(childFinal ? childFinal.startDate : child.startDate);\n const end = parseDateOnly(childFinal ? childFinal.endDate : child.endDate);\n if (!minStart || start.getTime() < minStart.getTime()) minStart = start;\n if (!maxEnd || end.getTime() > maxEnd.getTime()) maxEnd = end;\n }\n if (!minStart || !maxEnd) continue;\n const newStart = toIsoDate(minStart);\n const newEnd = toIsoDate(maxEnd);\n if (newStart === isoOfTaskDate(task.startDate) && newEnd === isoOfTaskDate(task.endDate)) {\n continue;\n }\n finalTasks.set(task.id, { ...task, startDate: newStart, endDate: newEnd });\n }\n\n // Selected parent: roll up from its direct children; dependencies untouched.\n const parentChildren = ctx.childrenByParentId.get(ctx.parentTask.id) ?? [];\n let parentStart: Date | null = null;\n let parentEnd: Date | null = null;\n for (const child of parentChildren) {\n const childFinal = finalTasks.get(child.id);\n const start = parseDateOnly(childFinal ? childFinal.startDate : child.startDate);\n const end = parseDateOnly(childFinal ? childFinal.endDate : child.endDate);\n if (!parentStart || start.getTime() < parentStart.getTime()) parentStart = start;\n if (!parentEnd || end.getTime() > parentEnd.getTime()) parentEnd = end;\n }\n if (parentStart && parentEnd) {\n const newStart = toIsoDate(parentStart);\n const newEnd = toIsoDate(parentEnd);\n if (\n newStart !== isoOfTaskDate(ctx.parentTask.startDate) ||\n newEnd !== isoOfTaskDate(ctx.parentTask.endDate)\n ) {\n finalTasks.set(ctx.parentTask.id, {\n ...ctx.parentTask,\n startDate: newStart,\n endDate: newEnd,\n });\n }\n }\n\n return finalTasks;\n}\n\nfunction findOutgoingViolations(\n ctx: ScalingContext,\n finalTasks: Map<string, Task>\n): string[] {\n const violations: string[] = [];\n const originalById = new Map(ctx.snapshot.map((task) => [task.id, task]));\n for (const ref of ctx.outgoingRefs) {\n const fromTask = finalTasks.get(ref.fromId) ?? originalById.get(ref.fromId);\n if (!fromTask) continue;\n const { predStart, predEnd } = normalizePredecessorDates(fromTask, parseDateOnly);\n const required = calculateSuccessorDate(\n predStart,\n predEnd,\n ref.type,\n ref.lag,\n ctx.businessDays,\n ctx.weekendPredicate,\n ref.succTask.type === 'milestone' ? 'milestone' : undefined\n );\n const succStart = parseDateOnly(ref.succTask.startDate);\n const succEnd =\n ref.succTask.type === 'milestone' ? succStart : parseDateOnly(ref.succTask.endDate);\n if (ref.type === 'FS' || ref.type === 'SS') {\n if (succStart.getTime() < required.getTime()) {\n violations.push(`${ref.type} ${ref.fromId} -> ${ref.succTask.id}`);\n }\n } else if (succEnd.getTime() < required.getTime()) {\n violations.push(`${ref.type} ${ref.fromId} -> ${ref.succTask.id}`);\n }\n }\n return violations;\n}\n\nfunction cascadeExternalSuccessors(\n ctx: ScalingContext,\n finalTasks: Map<string, Task>\n): { ok: true; changedExternal: Task[] } | { ok: false; details: string[] } {\n // Immutable external successors cancel the whole operation.\n const immutableExternal = new Set<string>();\n const seeds: string[] = [];\n for (const ref of ctx.outgoingRefs) {\n if (ctx.isImmutable(ref.succTask) || ref.succTask.locked === true) {\n immutableExternal.add(ref.succTask.id);\n }\n if (finalTasks.has(ref.fromId) && !seeds.includes(ref.fromId)) {\n seeds.push(ref.fromId);\n }\n }\n if (immutableExternal.size > 0) {\n return {\n ok: false,\n details: [`immutable external successor(s): ${[...immutableExternal].slice(0, 5).join(', ')}`],\n };\n }\n if (seeds.length === 0) return { ok: true, changedExternal: [] };\n\n // Working snapshot with all subtree changes applied; externals copied.\n const working = ctx.snapshot.map((task) => {\n const final = finalTasks.get(task.id);\n return final ?? { ...task };\n });\n\n const externalChanged = new Map<string, Task>();\n for (const seedId of seeds) {\n const seedTask = working.find((task) => task.id === seedId);\n if (!seedTask) continue;\n const cascade = universalCascade(\n seedTask,\n parseDateOnly(seedTask.startDate),\n parseDateOnly(seedTask.endDate),\n working,\n ctx.businessDays,\n ctx.weekendPredicate\n );\n for (const updated of cascade) {\n if (ctx.subtreeIds.has(updated.id) || updated.id === ctx.parentTask.id) continue;\n const beforeIndex = working.findIndex((task) => task.id === updated.id);\n if (beforeIndex < 0) continue;\n const before = working[beforeIndex];\n if (JSON.stringify(before) !== JSON.stringify(updated)) {\n externalChanged.set(updated.id, updated);\n }\n working.splice(beforeIndex, 1, updated);\n }\n }\n\n // Deterministic topological order over the changed external set.\n const changedSet = new Set(externalChanged.keys());\n const indegree = new Map<string, number>([...changedSet].map((id) => [id, 0]));\n for (const task of externalChanged.values()) {\n for (const dep of task.dependencies ?? []) {\n if (changedSet.has(dep.taskId)) {\n indegree.set(task.id, (indegree.get(task.id) ?? 0) + 1);\n }\n }\n }\n const snapshotIndexById = new Map(ctx.snapshot.map((task, index) => [task.id, index]));\n const ready = [...changedSet]\n .filter((id) => (indegree.get(id) ?? 0) === 0)\n .sort((left, right) => (snapshotIndexById.get(left) ?? 0) - (snapshotIndexById.get(right) ?? 0));\n const ordered: Task[] = [];\n const emitted = new Set<string>();\n while (ready.length > 0) {\n const currentId = ready.shift()!;\n const current = externalChanged.get(currentId)!;\n ordered.push(current);\n emitted.add(currentId);\n for (const [otherId, other] of externalChanged) {\n if (emitted.has(otherId)) continue;\n if (!(other.dependencies ?? []).some((dep) => dep.taskId === currentId)) continue;\n const next = (indegree.get(otherId) ?? 0) - 1;\n indegree.set(otherId, next);\n if (next === 0) {\n ready.push(otherId);\n ready.sort((left, right) => (snapshotIndexById.get(left) ?? 0) - (snapshotIndexById.get(right) ?? 0));\n }\n }\n }\n for (const id of changedSet) {\n if (!emitted.has(id)) ordered.push(externalChanged.get(id)!);\n }\n\n return { ok: true, changedExternal: ordered };\n}\n\n// END_BLOCK_MATERIALIZE_SCALE_RESULT\n\n// START_BLOCK_VALIDATE_SCALE_RESULT\n\nfunction validateFinalGraph(\n ctx: ScalingContext,\n finalTasks: Map<string, Task>,\n external: Task[]\n): string[] {\n if (finalTasks.size === 0 && external.length === 0) return [];\n const updates = new Map<string, Task>();\n for (const task of finalTasks.values()) updates.set(task.id, task);\n for (const task of external) updates.set(task.id, task);\n const finalSnapshot = ctx.snapshot.map((task) => updates.get(task.id) ?? task);\n const validation = validateDependencies(finalSnapshot);\n return validation.isValid\n ? []\n : validation.errors.slice(0, 5).map((error) => `${error.type}: ${error.taskId}`);\n}\n\n// END_BLOCK_VALIDATE_SCALE_RESULT\n\n// ---------------------------------------------------------------------------\n// Public operation\n// ---------------------------------------------------------------------------\n\n/**\n * Proportionally scale a parent task's subtree to an exact target duration.\n *\n * The input snapshot is never mutated; the operation returns one atomic batch\n * of changed tasks. Unreachable compression targets apply the proven minimum\n * span and report a TARGET_CLAMPED_TO_MINIMUM warning instead of failing.\n */\nexport function scaleTaskSubtreeDuration(\n parentId: string,\n targetDuration: number,\n snapshot: Task[],\n options?: ScaleTaskSubtreeOptions\n): ScaleTaskSubtreeResult {\n const resolvedOptions = options ?? {};\n const businessDays = resolvedOptions.businessDays ?? false;\n\n // Phase 1: validate before any computation.\n const validation = validateScaleInput(\n parentId,\n targetDuration,\n snapshot,\n businessDays,\n resolvedOptions.weekendPredicate\n );\n if (!validation.ok) {\n return scaleFailure(validation.code, validation.details);\n }\n\n // Phase 2: build the indexed working context.\n const built = buildScaleContext(validation.parentTask, snapshot, resolvedOptions);\n if (!built.ok) {\n return scaleFailure(built.code, built.details);\n }\n const { context: ctx, space } = built;\n\n // Phases 3-4: solve durations, then flexible gaps, with exact-range correction.\n const solved = solveScale(ctx, space, targetDuration);\n\n // Phase 5: materialize dates, roll up parents, apply external policy.\n const finalTasks = buildFinalTasks(ctx, solved.state, solved.layout, space);\n\n const externalPolicy = resolvedOptions.externalDependencyPolicy ?? 'subtree-only';\n let externalChanged: Task[] = [];\n if (externalPolicy === 'subtree-only') {\n const violations = findOutgoingViolations(ctx, finalTasks);\n if (violations.length > 0) {\n return scaleFailure('EXTERNAL_DEPENDENCY_CONFLICT', violations);\n }\n } else {\n const cascaded = cascadeExternalSuccessors(ctx, finalTasks);\n if (!cascaded.ok) {\n return scaleFailure('EXTERNAL_DEPENDENCY_CONFLICT', cascaded.details);\n }\n externalChanged = cascaded.changedExternal;\n }\n\n // Final validation of the produced graph.\n const finalErrors = validateFinalGraph(ctx, finalTasks, externalChanged);\n if (finalErrors.length > 0) {\n return scaleFailure('INVALID_DEPENDENCIES', finalErrors);\n }\n\n // Sparse result in canonical order:\n // 1. changed leaves in snapshot order,\n // 2. changed nested parents from deepest to the selected parent,\n // 3. external cascaded successors in topological order.\n const changedLeaves = ctx.leaves\n .filter((leaf) => finalTasks.has(leaf.id))\n .map((leaf) => finalTasks.get(leaf.id)!);\n const changedParents = [...ctx.nestedParents.map(({ task }) => task), ctx.parentTask]\n .filter((task) => finalTasks.has(task.id))\n .map((task) => finalTasks.get(task.id)!);\n\n const changedTasks = [...changedLeaves, ...changedParents, ...externalChanged];\n const seen = new Set<string>();\n const uniqueChanged = changedTasks.filter((task) => {\n if (seen.has(task.id)) return false;\n seen.add(task.id);\n return true;\n });\n\n const warnings: ScaleTaskSubtreeWarning[] = solved.clamped\n ? [\n {\n code: 'TARGET_CLAMPED_TO_MINIMUM' as const,\n requestedDuration: targetDuration,\n minimumDuration: solved.appliedSpan,\n },\n ]\n : [];\n\n return {\n ok: true,\n changedTasks: uniqueChanged,\n changedIds: uniqueChanged.map((task) => task.id),\n requestedDuration: targetDuration,\n appliedDuration: solved.appliedSpan,\n clamped: solved.clamped,\n warnings,\n };\n}\n"],"mappings":"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","names":["DAY_MS","DAY_MS","toIsoDate"]}
|