@outbuild-company/schedule-core 1.12.0 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,4 +1,17 @@
1
+ // src/activity-types/constants.ts
2
+ var ACTIVITY_TYPE = {
3
+ TASK: "task",
4
+ PROJECT: "project",
5
+ MILESTONE: "milestone"
6
+ };
7
+ var ACTIVITY_TYPES = Object.values(ACTIVITY_TYPE);
8
+ function isActivityType(value) {
9
+ return ACTIVITY_TYPES.includes(value);
10
+ }
11
+
1
12
  // src/types.ts
13
+ var NOTIFICATION_TYPE = {
14
+ CONSTRAINT: "constraint"};
2
15
  var WORK_TIME_DIRECTION = {
3
16
  FUTURE: "future",
4
17
  PAST: "past"
@@ -23,6 +36,11 @@ var STATUS = {
23
36
  WAITING: "Waiting",
24
37
  DOING: "Doing"
25
38
  };
39
+ var ENTITY_CHANGE_KIND = {
40
+ CREATED: "created",
41
+ UPDATED: "updated",
42
+ DELETED: "deleted"
43
+ };
26
44
 
27
45
  // src/constraints/index.ts
28
46
  var CONSTRAINT_TYPE = {
@@ -36,12 +54,12 @@ var CONSTRAINT_TYPE = {
36
54
  MFO: "mfo"
37
55
  };
38
56
  var VIOLATION_RULES = {
39
- mso: () => true,
40
- mfo: () => true,
41
- snlt: (constraint, projected) => constraint < projected,
42
- snet: (constraint, projected) => constraint > projected,
43
- fnlt: (constraint, projected) => constraint < projected,
44
- fnet: (constraint, projected) => constraint > projected
57
+ [CONSTRAINT_TYPE.MSO]: () => true,
58
+ [CONSTRAINT_TYPE.MFO]: () => true,
59
+ [CONSTRAINT_TYPE.SNLT]: (constraint, projected) => constraint < projected,
60
+ [CONSTRAINT_TYPE.SNET]: (constraint, projected) => constraint > projected,
61
+ [CONSTRAINT_TYPE.FNLT]: (constraint, projected) => constraint < projected,
62
+ [CONSTRAINT_TYPE.FNET]: (constraint, projected) => constraint > projected
45
63
  };
46
64
  function checkConstraintViolation(constraintType, constraintDate, projectedDate) {
47
65
  if (!constraintDate) return { violated: false };
@@ -53,16 +71,16 @@ function checkConstraintViolation(constraintType, constraintDate, projectedDate)
53
71
  return { violated: false };
54
72
  }
55
73
  var START_BASED_CONSTRAINTS = /* @__PURE__ */ new Set([
56
- "mso",
57
- "snet",
58
- "snlt"
74
+ CONSTRAINT_TYPE.MSO,
75
+ CONSTRAINT_TYPE.SNET,
76
+ CONSTRAINT_TYPE.SNLT
59
77
  ]);
60
78
  function pickProjectedDateForConstraint(constraintType, projectedStart, projectedEnd) {
61
79
  return START_BASED_CONSTRAINTS.has(constraintType) ? projectedStart : projectedEnd;
62
80
  }
63
81
  function buildConstraintNotification(constraintType, constraintDate, projectedDate) {
64
82
  return {
65
- type: "constraint",
83
+ type: NOTIFICATION_TYPE.CONSTRAINT,
66
84
  messageKey: "constraint_violation",
67
85
  data: {
68
86
  constraintType,
@@ -72,12 +90,30 @@ function buildConstraintNotification(constraintType, constraintDate, projectedDa
72
90
  };
73
91
  }
74
92
  var CONSTRAINT_CASES = {
75
- snet: { startOfDay: true, direction: WORK_TIME_DIRECTION.FUTURE },
76
- snlt: { startOfDay: true, direction: WORK_TIME_DIRECTION.PAST },
77
- fnet: { startOfDay: false, direction: WORK_TIME_DIRECTION.FUTURE },
78
- fnlt: { startOfDay: false, direction: WORK_TIME_DIRECTION.PAST },
79
- mso: { startOfDay: true, direction: WORK_TIME_DIRECTION.FUTURE },
80
- mfo: { startOfDay: false, direction: WORK_TIME_DIRECTION.PAST }
93
+ [CONSTRAINT_TYPE.SNET]: {
94
+ startOfDay: true,
95
+ direction: WORK_TIME_DIRECTION.FUTURE
96
+ },
97
+ [CONSTRAINT_TYPE.SNLT]: {
98
+ startOfDay: true,
99
+ direction: WORK_TIME_DIRECTION.PAST
100
+ },
101
+ [CONSTRAINT_TYPE.FNET]: {
102
+ startOfDay: false,
103
+ direction: WORK_TIME_DIRECTION.FUTURE
104
+ },
105
+ [CONSTRAINT_TYPE.FNLT]: {
106
+ startOfDay: false,
107
+ direction: WORK_TIME_DIRECTION.PAST
108
+ },
109
+ [CONSTRAINT_TYPE.MSO]: {
110
+ startOfDay: true,
111
+ direction: WORK_TIME_DIRECTION.FUTURE
112
+ },
113
+ [CONSTRAINT_TYPE.MFO]: {
114
+ startOfDay: false,
115
+ direction: WORK_TIME_DIRECTION.PAST
116
+ }
81
117
  };
82
118
  var startOfUtcDay = (d) => new Date(Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate()));
83
119
  var addUtcDays = (d, n) => new Date(d.getTime() + n * 864e5);
@@ -129,7 +165,9 @@ function computeConstraintBounds(activity, adapter) {
129
165
  latestEnd: null
130
166
  };
131
167
  const type = activity.constraintType;
132
- if (!type || type === "asap" || type === "alap") return empty;
168
+ if (!type || type === CONSTRAINT_TYPE.ASAP || type === CONSTRAINT_TYPE.ALAP) {
169
+ return empty;
170
+ }
133
171
  const constraintDate = getEffectiveConstraintDate(activity, adapter);
134
172
  if (!constraintDate) return empty;
135
173
  const endFromStart = (start) => adapter.calculateEndDate({
@@ -143,35 +181,35 @@ function computeConstraintBounds(activity, adapter) {
143
181
  task: activity
144
182
  });
145
183
  switch (type) {
146
- case "snet":
184
+ case CONSTRAINT_TYPE.SNET:
147
185
  return {
148
186
  earliestStart: constraintDate,
149
187
  latestStart: null,
150
188
  earliestEnd: endFromStart(constraintDate),
151
189
  latestEnd: null
152
190
  };
153
- case "snlt":
191
+ case CONSTRAINT_TYPE.SNLT:
154
192
  return {
155
193
  earliestStart: null,
156
194
  latestStart: constraintDate,
157
195
  earliestEnd: null,
158
196
  latestEnd: endFromStart(constraintDate)
159
197
  };
160
- case "fnet":
198
+ case CONSTRAINT_TYPE.FNET:
161
199
  return {
162
200
  earliestStart: startFromEnd(constraintDate),
163
201
  latestStart: null,
164
202
  earliestEnd: constraintDate,
165
203
  latestEnd: null
166
204
  };
167
- case "fnlt":
205
+ case CONSTRAINT_TYPE.FNLT:
168
206
  return {
169
207
  earliestStart: null,
170
208
  latestStart: startFromEnd(constraintDate),
171
209
  earliestEnd: null,
172
210
  latestEnd: constraintDate
173
211
  };
174
- case "mso": {
212
+ case CONSTRAINT_TYPE.MSO: {
175
213
  const end = endFromStart(constraintDate);
176
214
  return {
177
215
  earliestStart: constraintDate,
@@ -180,7 +218,7 @@ function computeConstraintBounds(activity, adapter) {
180
218
  latestEnd: end
181
219
  };
182
220
  }
183
- case "mfo": {
221
+ case CONSTRAINT_TYPE.MFO: {
184
222
  const start = startFromEnd(constraintDate);
185
223
  return {
186
224
  earliestStart: start,
@@ -208,13 +246,17 @@ function clampStartToBounds(candidate, bounds) {
208
246
  return candidate;
209
247
  }
210
248
 
211
- // src/autoscheduler/types.ts
249
+ // src/autoscheduler/links/constants.ts
212
250
  var LINK_TYPE = {
213
251
  FINISH_TO_START: "0",
214
252
  START_TO_START: "1",
215
253
  FINISH_TO_FINISH: "2",
216
254
  START_TO_FINISH: "3"
217
255
  };
256
+ var LINK_TYPES = Object.values(LINK_TYPE);
257
+ function isLinkType(value) {
258
+ return LINK_TYPES.includes(value);
259
+ }
218
260
 
219
261
  // src/constants/columns.ts
220
262
  var EDITABLE = {
@@ -300,6 +342,7 @@ var DISPATCH_ACTION_KIND = {
300
342
  ACTIVITY_INDENT: "activity-indent",
301
343
  ACTIVITY_OUTDENT: "activity-outdent",
302
344
  ACTIVITY_SET_PROGRESS: "activity-set-progress",
345
+ ACTIVITY_LOOKAHEAD_CONVERT: "activity-lookahead-convert",
303
346
  SELECTION_TOGGLE: "selection-toggle",
304
347
  SELECTION_REPLACE: "selection-replace",
305
348
  VISIBILITY_SET: "visibility-set",
@@ -382,14 +425,14 @@ function activityEditToColumnEdit(activityId, edit) {
382
425
  }
383
426
 
384
427
  // src/api/schedule-api.ts
385
- var LINK_TYPES = {
428
+ var LINK_TYPES2 = {
386
429
  [LINK_RELATIONSHIP.FINISH_TO_START]: LINK_TYPE.FINISH_TO_START,
387
430
  [LINK_RELATIONSHIP.START_TO_START]: LINK_TYPE.START_TO_START,
388
431
  [LINK_RELATIONSHIP.FINISH_TO_FINISH]: LINK_TYPE.FINISH_TO_FINISH,
389
432
  [LINK_RELATIONSHIP.START_TO_FINISH]: LINK_TYPE.START_TO_FINISH
390
433
  };
391
434
  function linkType(relationship) {
392
- return LINK_TYPES[relationship];
435
+ return LINK_TYPES2[relationship];
393
436
  }
394
437
  function batchLink(operation) {
395
438
  if (operation.kind === LINK_BATCH_OPERATION_KIND.CREATE) {
@@ -491,6 +534,8 @@ function createActivitiesApi(engine) {
491
534
  { ...input, kind: DISPATCH_ACTION_KIND.ACTIVITY_MOVE },
492
535
  options
493
536
  ),
537
+ planLookaheadConversion: (input) => engine.planLookaheadConversion(input),
538
+ applyLookaheadConversion: (input) => engine.applyLookaheadConversion(input),
494
539
  indent: (activityIds, context = {}) => engine.dispatch({
495
540
  ...context,
496
541
  kind: DISPATCH_ACTION_KIND.ACTIVITY_INDENT,
@@ -669,6 +714,7 @@ function createScheduleNamespaces(engine) {
669
714
  diagnostics: {
670
715
  auditEffectiveGraph: () => engine.auditEffectiveGraph(),
671
716
  revision: () => engine.getScheduleRevision(),
717
+ stateRevision: () => engine.getStateRevision(),
672
718
  canonicalDigest: () => engine.getCanonicalDigest()
673
719
  }
674
720
  };
@@ -820,6 +866,7 @@ var REJECTION_REASON = {
820
866
  OUTDENT_ROOT_LEVEL_NOT_EDITABLE: "outdent_root_level_not_editable",
821
867
  HIERARCHY_CYCLE: "hierarchy_cycle",
822
868
  SANDBOX_PERSISTENCE_FORBIDDEN: "sandbox_persistence_forbidden",
869
+ STALE_STATE_REVISION: "stale-state-revision",
823
870
  INVALID_PROGRESS_VALUE: "invalid_progress_value_must_be_0_or_100"
824
871
  };
825
872
 
@@ -924,11 +971,6 @@ function dispatchVisibilitySet(action, deps) {
924
971
  }
925
972
 
926
973
  // src/autoscheduler/constants.ts
927
- var ACTIVITY_TYPE = {
928
- TASK: "task",
929
- PROJECT: "project",
930
- MILESTONE: "milestone"
931
- };
932
974
  var TIMING = {
933
975
  YIELD_SLICE_MS: 8
934
976
  };
@@ -1971,53 +2013,55 @@ function filterTopoOrder(order, scopedIds) {
1971
2013
  }
1972
2014
 
1973
2015
  // src/activity-types/behavior.ts
2016
+ var PONDERATOR_WEIGHT = {
2017
+ OWN_BASELINE: "own-baseline",
2018
+ RECURSIVE_LEAF_SUM: "recursive-leaf-sum",
2019
+ ZERO: "zero"
2020
+ };
1974
2021
  var ACTIVITY_TYPE_BEHAVIOR = {
1975
- project: {
2022
+ [ACTIVITY_TYPE.PROJECT]: {
1976
2023
  alwaysSummary: true,
1977
2024
  holdsConstraint: false,
1978
2025
  carriesCustomId: false,
1979
2026
  forcedDuration: null,
1980
- ponderatorWeight: "recursive-leaf-sum",
2027
+ ponderatorWeight: PONDERATOR_WEIGHT.RECURSIVE_LEAF_SUM,
1981
2028
  promotesToProjectOnFirstChild: false
1982
2029
  },
1983
- task: {
2030
+ [ACTIVITY_TYPE.TASK]: {
1984
2031
  alwaysSummary: false,
1985
2032
  holdsConstraint: true,
1986
2033
  carriesCustomId: true,
1987
2034
  forcedDuration: null,
1988
- ponderatorWeight: "own-baseline",
2035
+ ponderatorWeight: PONDERATOR_WEIGHT.OWN_BASELINE,
1989
2036
  promotesToProjectOnFirstChild: true
1990
2037
  },
1991
- milestone: {
2038
+ [ACTIVITY_TYPE.MILESTONE]: {
1992
2039
  alwaysSummary: false,
1993
2040
  holdsConstraint: true,
1994
2041
  carriesCustomId: true,
1995
2042
  forcedDuration: 0,
1996
- ponderatorWeight: "zero",
2043
+ ponderatorWeight: PONDERATOR_WEIGHT.ZERO,
1997
2044
  promotesToProjectOnFirstChild: true
1998
2045
  }
1999
2046
  };
2000
2047
 
2001
2048
  // src/activity-types/predicates.ts
2002
- function isActivityType(value) {
2003
- return value === "project" || value === "task" || value === "milestone";
2004
- }
2005
2049
  function isSummary(type, hasChildren) {
2006
2050
  return hasChildren || isActivityType(type) && ACTIVITY_TYPE_BEHAVIOR[type].alwaysSummary;
2007
2051
  }
2008
2052
  function isMilestoneType(type) {
2009
- return type === "milestone";
2053
+ return type === ACTIVITY_TYPE.MILESTONE;
2010
2054
  }
2011
2055
  function isPromotableLeafType(type) {
2012
2056
  return isActivityType(type) && ACTIVITY_TYPE_BEHAVIOR[type].promotesToProjectOnFirstChild;
2013
2057
  }
2014
2058
 
2015
2059
  // src/activity-types/transitions.ts
2016
- var PROMOTION_TARGET_TYPE = "project";
2017
- var DEMOTION_TARGET_TYPE = "task";
2060
+ var PROMOTION_TARGET_TYPE = ACTIVITY_TYPE.PROJECT;
2061
+ var DEMOTION_TARGET_TYPE = ACTIVITY_TYPE.TASK;
2018
2062
  function typeForNewDuration(currentDuration, newDuration) {
2019
- if (newDuration === 0) return "milestone";
2020
- if (currentDuration === 0 && newDuration > 0) return "task";
2063
+ if (newDuration === 0) return ACTIVITY_TYPE.MILESTONE;
2064
+ if (currentDuration === 0 && newDuration > 0) return ACTIVITY_TYPE.TASK;
2021
2065
  return null;
2022
2066
  }
2023
2067
 
@@ -2603,7 +2647,7 @@ function processConstraints(activityIds, adapter, plans) {
2603
2647
  startDate: activity.startDate,
2604
2648
  endDate: activity.endDate,
2605
2649
  drivingLinkId: null,
2606
- kind: "asap",
2650
+ kind: CONSTRAINT_TYPE.ASAP,
2607
2651
  conflict: false,
2608
2652
  earliestStart: bounds.earliestStart,
2609
2653
  latestStart: bounds.latestStart,
@@ -2755,7 +2799,7 @@ async function asapPass(orderedIds, links, adapter, options, isCurrent, plans) {
2755
2799
  startDate: activity.startDate,
2756
2800
  endDate: activity.endDate,
2757
2801
  drivingLinkId: null,
2758
- kind: "asap",
2802
+ kind: CONSTRAINT_TYPE.ASAP,
2759
2803
  conflict: false
2760
2804
  };
2761
2805
  const hasConstraintBounds = plan.earliestStart || plan.latestStart || plan.earliestEnd || plan.latestEnd;
@@ -2959,13 +3003,13 @@ async function alapPass(reversedIds, links, asapPlans, adapter, _options, isCurr
2959
3003
  startDate: snappedStart,
2960
3004
  endDate: snappedEnd,
2961
3005
  drivingLinkId: null,
2962
- kind: "alap",
3006
+ kind: CONSTRAINT_TYPE.ALAP,
2963
3007
  conflict: false
2964
3008
  };
2965
3009
  plan.startDate = snappedStart;
2966
3010
  plan.endDate = snappedEnd;
2967
3011
  plan.drivingLinkId = null;
2968
- plan.kind = "alap";
3012
+ plan.kind = CONSTRAINT_TYPE.ALAP;
2969
3013
  const predecessorFloor = plan.earliestSchedulingStart ?? null;
2970
3014
  plan.earliestSchedulingStart = null;
2971
3015
  plan.earliestSchedulingEnd = null;
@@ -2993,7 +3037,7 @@ var noopReporter = {
2993
3037
  // src/internal/state/calendar-duration.ts
2994
3038
  var CALENDAR_DAY_MS = 864e5;
2995
3039
  function computeCalendarDuration(activity) {
2996
- if (activity.type === "milestone") return 0;
3040
+ if (activity.type === ACTIVITY_TYPE.MILESTONE) return 0;
2997
3041
  const start = activity.startDate?.getTime();
2998
3042
  const end = activity.endDate?.getTime();
2999
3043
  if (start == null || end == null || Number.isNaN(start) || Number.isNaN(end)) {
@@ -3300,8 +3344,12 @@ var ReparentedPort = class {
3300
3344
 
3301
3345
  // src/internal/dependency-graph/effective-graph-validation.ts
3302
3346
  function validateTopologyCommit(input) {
3303
- const { port, currentLinks, proposedLinks, proposal } = input;
3304
- const proposedEdges = projectEffectiveEdges(port, proposedLinks, proposal);
3347
+ const { port, proposedPort, currentLinks, proposedLinks, proposal } = input;
3348
+ const proposedEdges = projectEffectiveEdges(
3349
+ proposedPort ?? port,
3350
+ proposedLinks,
3351
+ proposal
3352
+ );
3305
3353
  if (!hasDirectedCycle(proposedEdges)) return { ok: true };
3306
3354
  const currentEdges = projectEffectiveEdges(port, currentLinks);
3307
3355
  const corruptBefore = corruptActivityIds(currentEdges);
@@ -3511,19 +3559,25 @@ function defaultNewLinkId() {
3511
3559
  }
3512
3560
 
3513
3561
  // src/autoscheduler/links/link-display.ts
3562
+ var LINK_CODE = {
3563
+ FINISH_TO_START: "fs",
3564
+ START_TO_START: "ss",
3565
+ FINISH_TO_FINISH: "ff",
3566
+ START_TO_FINISH: "sf"
3567
+ };
3514
3568
  var LINK_TYPE_CODE = {
3515
- [LINK_TYPE.FINISH_TO_START]: "fs",
3516
- [LINK_TYPE.START_TO_START]: "ss",
3517
- [LINK_TYPE.FINISH_TO_FINISH]: "ff",
3518
- [LINK_TYPE.START_TO_FINISH]: "sf"
3569
+ [LINK_TYPE.FINISH_TO_START]: LINK_CODE.FINISH_TO_START,
3570
+ [LINK_TYPE.START_TO_START]: LINK_CODE.START_TO_START,
3571
+ [LINK_TYPE.FINISH_TO_FINISH]: LINK_CODE.FINISH_TO_FINISH,
3572
+ [LINK_TYPE.START_TO_FINISH]: LINK_CODE.START_TO_FINISH
3519
3573
  };
3520
3574
  var LINK_CODE_TO_TYPE = {
3521
- fs: LINK_TYPE.FINISH_TO_START,
3522
- ss: LINK_TYPE.START_TO_START,
3523
- ff: LINK_TYPE.FINISH_TO_FINISH,
3524
- sf: LINK_TYPE.START_TO_FINISH
3575
+ [LINK_CODE.FINISH_TO_START]: LINK_TYPE.FINISH_TO_START,
3576
+ [LINK_CODE.START_TO_START]: LINK_TYPE.START_TO_START,
3577
+ [LINK_CODE.FINISH_TO_FINISH]: LINK_TYPE.FINISH_TO_FINISH,
3578
+ [LINK_CODE.START_TO_FINISH]: LINK_TYPE.START_TO_FINISH
3525
3579
  };
3526
- var DEFAULT_LINK_CODE = "fs";
3580
+ var DEFAULT_LINK_CODE = LINK_CODE.FINISH_TO_START;
3527
3581
  function parseLinkTypeCode(raw) {
3528
3582
  if (raw in LINK_CODE_TO_TYPE) {
3529
3583
  return LINK_CODE_TO_TYPE[raw];
@@ -3589,20 +3643,24 @@ function diffLinks(input) {
3589
3643
  const operations = [];
3590
3644
  for (const [key, link] of currentByKey) {
3591
3645
  if (!desired.has(key)) {
3592
- operations.push({ kind: "delete", linkId: link.id });
3646
+ operations.push({ kind: LINK_OPERATION_KIND.DELETE, linkId: link.id });
3593
3647
  }
3594
3648
  }
3595
3649
  for (const [key, spec] of desired) {
3596
3650
  const existing = currentByKey.get(key);
3597
3651
  if (!existing) continue;
3598
3652
  if (existing.lag !== spec.lag) {
3599
- operations.push({ kind: "update", linkId: existing.id, lag: spec.lag });
3653
+ operations.push({
3654
+ kind: LINK_OPERATION_KIND.UPDATE,
3655
+ linkId: existing.id,
3656
+ lag: spec.lag
3657
+ });
3600
3658
  }
3601
3659
  }
3602
3660
  for (const [key, spec] of desired) {
3603
3661
  if (currentByKey.has(key)) continue;
3604
3662
  operations.push({
3605
- kind: "create",
3663
+ kind: LINK_OPERATION_KIND.CREATE,
3606
3664
  source: spec.source,
3607
3665
  target: targetActivityId,
3608
3666
  type: spec.type,
@@ -3636,20 +3694,24 @@ function diffOutgoingLinks(input) {
3636
3694
  const operations = [];
3637
3695
  for (const [key, link] of currentByKey) {
3638
3696
  if (!desired.has(key)) {
3639
- operations.push({ kind: "delete", linkId: link.id });
3697
+ operations.push({ kind: LINK_OPERATION_KIND.DELETE, linkId: link.id });
3640
3698
  }
3641
3699
  }
3642
3700
  for (const [key, spec] of desired) {
3643
3701
  const existing = currentByKey.get(key);
3644
3702
  if (!existing) continue;
3645
3703
  if (existing.lag !== spec.lag) {
3646
- operations.push({ kind: "update", linkId: existing.id, lag: spec.lag });
3704
+ operations.push({
3705
+ kind: LINK_OPERATION_KIND.UPDATE,
3706
+ linkId: existing.id,
3707
+ lag: spec.lag
3708
+ });
3647
3709
  }
3648
3710
  }
3649
3711
  for (const [key, spec] of desired) {
3650
3712
  if (currentByKey.has(key)) continue;
3651
3713
  operations.push({
3652
- kind: "create",
3714
+ kind: LINK_OPERATION_KIND.CREATE,
3653
3715
  source: sourceActivityId,
3654
3716
  target: spec.target,
3655
3717
  type: spec.type,
@@ -3693,13 +3755,13 @@ var currentImpl = {
3693
3755
  // src/autoscheduler/date-math/types.ts
3694
3756
  function pickDatesForLinkType(source, target, linkType2) {
3695
3757
  switch (linkType2) {
3696
- case "0":
3758
+ case LINK_TYPE.FINISH_TO_START:
3697
3759
  return { sourceDate: source.endDate, targetDate: target.startDate };
3698
- case "1":
3760
+ case LINK_TYPE.START_TO_START:
3699
3761
  return { sourceDate: source.startDate, targetDate: target.startDate };
3700
- case "2":
3762
+ case LINK_TYPE.FINISH_TO_FINISH:
3701
3763
  return { sourceDate: source.endDate, targetDate: target.endDate };
3702
- case "3":
3764
+ case LINK_TYPE.START_TO_FINISH:
3703
3765
  return { sourceDate: source.startDate, targetDate: target.endDate };
3704
3766
  }
3705
3767
  }
@@ -3832,7 +3894,7 @@ var AutoScheduler = class {
3832
3894
  };
3833
3895
  } catch (error) {
3834
3896
  this.reporter.error("[AutoScheduler] Error during scheduling", error);
3835
- return emptyResult;
3897
+ throw error;
3836
3898
  }
3837
3899
  }
3838
3900
  };
@@ -3912,7 +3974,7 @@ function adjustLinkLagOnTaskMove(targetId, adapter, preEditTarget) {
3912
3974
  if (!link) continue;
3913
3975
  const source = adapter.getActivity(link.source);
3914
3976
  if (!source) continue;
3915
- if (source.constraintType === "alap") continue;
3977
+ if (source.constraintType === CONSTRAINT_TYPE.ALAP) continue;
3916
3978
  const isEndAnchoredIntoMilestone = isMilestoneType(target.type) && (link.type === LINK_TYPE.START_TO_FINISH || link.type === LINK_TYPE.FINISH_TO_FINISH);
3917
3979
  if (isEndAnchoredIntoMilestone) continue;
3918
3980
  const { sourceDate, targetDate } = pickDatesForLinkType(
@@ -3926,7 +3988,10 @@ function adjustLinkLagOnTaskMove(targetId, adapter, preEditTarget) {
3926
3988
  calendarApi
3927
3989
  );
3928
3990
  if (newLag === link.lag) continue;
3929
- applyLinkUpdate({ linkId: link.id, lag: newLag }, adapter);
3991
+ applyLinkUpdate(
3992
+ { kind: LINK_OPERATION_KIND.UPDATE, linkId: link.id, lag: newLag },
3993
+ adapter
3994
+ );
3930
3995
  }
3931
3996
  }
3932
3997
 
@@ -4038,15 +4103,19 @@ function computeLeafRealWork(workHours, progress) {
4038
4103
  }
4039
4104
 
4040
4105
  // src/propagations/upward/parent-bounds.ts
4106
+ var PARENT_PROGRESS_MODE = {
4107
+ SKIP: "skip",
4108
+ FREEZE_WITHOUT_CONTRIBUTION: "freeze-when-no-contribution"
4109
+ };
4041
4110
  async function updateParentBoundsFromChildren(adapter, dirtyIds, recomputeProgress = true, options = {}) {
4042
4111
  const parents = dirtyIds ? findAncestorsOfDirty(adapter, dirtyIds) : findAllParents(adapter);
4043
- const progressMode = recomputeProgress ? options.progressMode ?? "freeze-when-no-contribution" : "skip";
4112
+ const progressMode = recomputeProgress ? options.progressMode ?? PARENT_PROGRESS_MODE.FREEZE_WITHOUT_CONTRIBUTION : PARENT_PROGRESS_MODE.SKIP;
4044
4113
  await recomputeParentsCooperatively(parents, adapter, progressMode, {
4045
4114
  recomputeRealWork: options.recomputeRealWork ?? false
4046
4115
  });
4047
4116
  }
4048
4117
  function recomputeSingleParentDisplayBounds(parentId, adapter) {
4049
- recomputeParentFromChildren(parentId, adapter, "skip");
4118
+ recomputeParentFromChildren(parentId, adapter, PARENT_PROGRESS_MODE.SKIP);
4050
4119
  }
4051
4120
  async function recomputeParentsCooperatively(parents, adapter, progressMode, options = {
4052
4121
  recomputeRealWork: false
@@ -4132,7 +4201,7 @@ function aggregateChildren(childrenIds, adapter, includeRealWork) {
4132
4201
  }
4133
4202
  return { minStart, maxEnd, realWorkSum, weightedChildren };
4134
4203
  }
4135
- function recomputeParentFromChildren(parentId, adapter, progressMode = "freeze-when-no-contribution", recomputeRealWork = false) {
4204
+ function recomputeParentFromChildren(parentId, adapter, progressMode = PARENT_PROGRESS_MODE.FREEZE_WITHOUT_CONTRIBUTION, recomputeRealWork = false) {
4136
4205
  const parent = adapter.getActivity(parentId);
4137
4206
  if (!parent) return;
4138
4207
  const childrenIds = adapter.getChildren(parentId);
@@ -4147,7 +4216,7 @@ function recomputeParentFromChildren(parentId, adapter, progressMode = "freeze-w
4147
4216
  adapter.setActivityField(parentId, "startDate", newStart);
4148
4217
  adapter.setActivityField(parentId, "endDate", newEnd);
4149
4218
  adapter.setActivityField(parentId, "durationHours", durationHours);
4150
- if (progressMode !== "skip") {
4219
+ if (progressMode !== PARENT_PROGRESS_MODE.SKIP) {
4151
4220
  applyWeightedProgressRollup(parentId, aggregate.weightedChildren, adapter);
4152
4221
  }
4153
4222
  if (recomputeRealWork) {
@@ -4254,6 +4323,21 @@ function fieldChanges(patch, options = {}) {
4254
4323
  };
4255
4324
  }
4256
4325
 
4326
+ // src/columns/shared/tracking-events.ts
4327
+ var COLUMN_TRACK_EVENT = {
4328
+ PROGRESS_ENTRY: "activity_progress_entry",
4329
+ PROGRESS_UPDATE_RADIO_BUTTON: "activity_progress_update_radio_button",
4330
+ DURATION_ENTRY: "activity_duration_entry",
4331
+ START_DATE_ENTRY: "activity_start_date_entry",
4332
+ END_DATE_ENTRY: "activity_end_date_entry",
4333
+ NAME_ENTRY: "activity_name_entry",
4334
+ DESCRIPTION_ENTRY: "activity_description_entry",
4335
+ CALENDAR_ASSIGNMENT: "activity_calendar_assignment",
4336
+ COST_BUDGETED_ENTRY: "activity_cost_budgeted_entry",
4337
+ COST_SPENT_ENTRY: "activity_cost_spent_entry",
4338
+ LABOR_HOURS_BUDGETED_ENTRY: "activity_labor_hours_budgeted_entry"
4339
+ };
4340
+
4257
4341
  // src/columns/text/text-pipeline.ts
4258
4342
  var textPipeline = {
4259
4343
  targetField: "name",
@@ -4273,7 +4357,7 @@ var textPipeline = {
4273
4357
  postProcessors: []
4274
4358
  });
4275
4359
  },
4276
- trackEvent: "activity_name_entry"
4360
+ trackEvent: COLUMN_TRACK_EVENT.NAME_ENTRY
4277
4361
  };
4278
4362
 
4279
4363
  // src/columns/description/description-pipeline.ts
@@ -4295,7 +4379,7 @@ var descriptionPipeline = {
4295
4379
  { autoSchedule: false, postProcessors: [] }
4296
4380
  );
4297
4381
  },
4298
- trackEvent: "activity_description_entry"
4382
+ trackEvent: COLUMN_TRACK_EVENT.DESCRIPTION_ENTRY
4299
4383
  };
4300
4384
 
4301
4385
  // src/columns/shared/activity-predicates.ts
@@ -4327,6 +4411,7 @@ var setEndDate = (value) => ({
4327
4411
  });
4328
4412
 
4329
4413
  // src/columns/shared/date-normalize.ts
4414
+ var UTC_TIME_ZONE = "UTC";
4330
4415
  function truncateToUtcDay(date2, tz) {
4331
4416
  {
4332
4417
  const parts = new Intl.DateTimeFormat("en-CA", {
@@ -4347,11 +4432,11 @@ function endOfLocalDay(date2, tz) {
4347
4432
  }
4348
4433
  }
4349
4434
  function nextWorkingDay(calendar, domainDay) {
4350
- let cursor = truncateToUtcDay(domainDay, "UTC");
4435
+ let cursor = truncateToUtcDay(domainDay, UTC_TIME_ZONE);
4351
4436
  while (!calendar.isWorkTime(cursor, CALENDAR_UNIT.DAY)) {
4352
4437
  cursor = new Date(cursor);
4353
4438
  cursor.setUTCDate(cursor.getUTCDate() + 1);
4354
- cursor = truncateToUtcDay(cursor, "UTC");
4439
+ cursor = truncateToUtcDay(cursor, UTC_TIME_ZONE);
4355
4440
  }
4356
4441
  return cursor;
4357
4442
  }
@@ -4374,22 +4459,22 @@ function shiftEnd(calendar, domainDay) {
4374
4459
  });
4375
4460
  }
4376
4461
  var START_BASED_CONSTRAINTS2 = /* @__PURE__ */ new Set([
4377
- "snet",
4378
- "snlt",
4379
- "mso"
4462
+ CONSTRAINT_TYPE.SNET,
4463
+ CONSTRAINT_TYPE.SNLT,
4464
+ CONSTRAINT_TYPE.MSO
4380
4465
  ]);
4381
4466
  var END_BASED_CONSTRAINTS = /* @__PURE__ */ new Set([
4382
- "fnet",
4383
- "fnlt",
4384
- "mfo"
4467
+ CONSTRAINT_TYPE.FNET,
4468
+ CONSTRAINT_TYPE.FNLT,
4469
+ CONSTRAINT_TYPE.MFO
4385
4470
  ]);
4386
4471
  var DATELESS_CONSTRAINTS = /* @__PURE__ */ new Set([
4387
- "asap",
4388
- "alap"
4472
+ CONSTRAINT_TYPE.ASAP,
4473
+ CONSTRAINT_TYPE.ALAP
4389
4474
  ]);
4390
- var IMPLIED_CONSTRAINT_ON_DATE_EDIT = "snet";
4475
+ var IMPLIED_CONSTRAINT_ON_DATE_EDIT = CONSTRAINT_TYPE.SNET;
4391
4476
  function normalizeConstraintDate(typedDay, calendar, constraintType) {
4392
- const constraintDay = truncateToUtcDay(typedDay, "UTC");
4477
+ const constraintDay = truncateToUtcDay(typedDay, UTC_TIME_ZONE);
4393
4478
  if (!START_BASED_CONSTRAINTS2.has(constraintType) && !END_BASED_CONSTRAINTS.has(constraintType)) {
4394
4479
  return constraintDay;
4395
4480
  }
@@ -4425,6 +4510,9 @@ var POST_PROCESSOR = {
4425
4510
  // src/columns/shared/error-codes.ts
4426
4511
  var VALIDATION_REASON = {
4427
4512
  NEGATIVE_DURATION: "negative_duration"};
4513
+ var EDIT_DENIAL_REASON = {
4514
+ SUMMARY: "summary",
4515
+ HAS_LOOKAHEAD_TASKS: "has_lookahead_tasks"};
4428
4516
 
4429
4517
  // src/columns/shared/constraint-validation.ts
4430
4518
  function checkConstraintViolation2(constraintType, constraintDate, projectedDate) {
@@ -4489,7 +4577,7 @@ var durationPipeline = {
4489
4577
  } : {}
4490
4578
  };
4491
4579
  },
4492
- trackEvent: "activity_duration_entry"
4580
+ trackEvent: COLUMN_TRACK_EVENT.DURATION_ENTRY
4493
4581
  };
4494
4582
  function isNegativeDuration(value) {
4495
4583
  return Math.sign(value) === -1;
@@ -4501,7 +4589,7 @@ function checkDurationAgainstConstraints(activity, newDuration, ctx) {
4501
4589
  const calendar = ctx.calendars.getCalendar(activity.calendarId);
4502
4590
  if (!calendar) return { violated: false };
4503
4591
  const type = activity.constraintType;
4504
- if (type !== "fnet" && type !== "fnlt" && type !== "mfo") {
4592
+ if (type !== CONSTRAINT_TYPE.FNET && type !== CONSTRAINT_TYPE.FNLT && type !== CONSTRAINT_TYPE.MFO) {
4505
4593
  return { violated: false };
4506
4594
  }
4507
4595
  const projectedEnd = calendar.calculateEndDate(
@@ -4594,7 +4682,7 @@ var progressPipeline = {
4594
4682
  trackingEvents
4595
4683
  });
4596
4684
  },
4597
- trackEvent: "activity_progress_entry"
4685
+ trackEvent: COLUMN_TRACK_EVENT.PROGRESS_ENTRY
4598
4686
  };
4599
4687
  function isOutOfRange(value) {
4600
4688
  return value < MIN_PROGRESS || value > MAX_PROGRESS;
@@ -4674,7 +4762,7 @@ function computeWeightedProgress(parentId, overlay, hierarchy) {
4674
4762
  function buildRecursiveTrackingEvents(activity, newValue) {
4675
4763
  return [
4676
4764
  {
4677
- name: "activity_progress_update_radio_button",
4765
+ name: COLUMN_TRACK_EVENT.PROGRESS_UPDATE_RADIO_BUTTON,
4678
4766
  properties: {
4679
4767
  activity_id: activity.id,
4680
4768
  activity_name: activity.name,
@@ -4714,7 +4802,7 @@ var costPipeline = {
4714
4802
  cascadeMutations
4715
4803
  });
4716
4804
  },
4717
- trackEvent: "activity_cost_budgeted_entry"
4805
+ trackEvent: COLUMN_TRACK_EVENT.COST_BUDGETED_ENTRY
4718
4806
  };
4719
4807
  function buildCostAncestorCascade(activity, newCost, hierarchy) {
4720
4808
  const overlay = /* @__PURE__ */ new Map();
@@ -4767,7 +4855,7 @@ var usedCostPipeline = {
4767
4855
  }
4768
4856
  );
4769
4857
  },
4770
- trackEvent: "activity_cost_spent_entry"
4858
+ trackEvent: COLUMN_TRACK_EVENT.COST_SPENT_ENTRY
4771
4859
  };
4772
4860
  function buildUsedCostAncestorCascade(activity, newUsedCost, hierarchy) {
4773
4861
  const overlay = /* @__PURE__ */ new Map();
@@ -4822,7 +4910,7 @@ var hhWorkTimePipeline = {
4822
4910
  }
4823
4911
  );
4824
4912
  },
4825
- trackEvent: "activity_labor_hours_budgeted_entry"
4913
+ trackEvent: COLUMN_TRACK_EVENT.LABOR_HOURS_BUDGETED_ENTRY
4826
4914
  };
4827
4915
  function computeRealWork(hhWorkTime, progress) {
4828
4916
  return computeLeafRealWork(hhWorkTime, progress);
@@ -4915,7 +5003,7 @@ var startDatePipeline = {
4915
5003
  throw new Error("startDatePipeline: no calendar resolved (integrity)");
4916
5004
  }
4917
5005
  const finalStart = shiftStart(calendar, newValue);
4918
- const milestoneActivity = activity.type === "milestone";
5006
+ const milestoneActivity = activity.type === ACTIVITY_TYPE.MILESTONE;
4919
5007
  const finalEnd = milestoneActivity ? finalStart : calendar.calculateEndDate(finalStart, activity.durationHours);
4920
5008
  const constraintDate = finalStart;
4921
5009
  return {
@@ -4935,7 +5023,7 @@ var startDatePipeline = {
4935
5023
  constraintWarning: detectConstraintWarning(activity, finalStart, calendar)
4936
5024
  };
4937
5025
  },
4938
- trackEvent: "activity_start_date_entry"
5026
+ trackEvent: COLUMN_TRACK_EVENT.START_DATE_ENTRY
4939
5027
  };
4940
5028
  function checkParentStartConstraint(activity, newDate, ctx) {
4941
5029
  const parentStartDate = ctx.hierarchy.getParentStartDateIfHasPredecessors(
@@ -5029,7 +5117,7 @@ var endDatePipeline = {
5029
5117
  ...constraintWarning ? { constraintWarning } : {}
5030
5118
  };
5031
5119
  },
5032
- trackEvent: "activity_end_date_entry"
5120
+ trackEvent: COLUMN_TRACK_EVENT.END_DATE_ENTRY
5033
5121
  };
5034
5122
  function isNearlyCompleted(activity) {
5035
5123
  return activity.progress >= NEAR_COMPLETE_THRESHOLD;
@@ -5140,7 +5228,9 @@ function buildConstraintTypeExtraFields(activity, newType, ctx) {
5140
5228
  };
5141
5229
  }
5142
5230
  function normalizeMilestoneConstraintDate(activity, newType, derivedDate, ctx) {
5143
- if (activity.type !== "milestone" || !derivedDate) return derivedDate;
5231
+ if (activity.type !== ACTIVITY_TYPE.MILESTONE || !derivedDate) {
5232
+ return derivedDate;
5233
+ }
5144
5234
  const calendar = ctx.calendars.getCalendar(String(activity.calendarId));
5145
5235
  if (!calendar) return derivedDate;
5146
5236
  return normalizeConstraintDate(derivedDate, calendar, newType);
@@ -5218,7 +5308,7 @@ var calendarIdPipeline = {
5218
5308
  postProcessors: []
5219
5309
  });
5220
5310
  },
5221
- trackEvent: "activity_calendar_assignment"
5311
+ trackEvent: COLUMN_TRACK_EVENT.CALENDAR_ASSIGNMENT
5222
5312
  };
5223
5313
  function isEmpty(value) {
5224
5314
  return value === "";
@@ -5300,8 +5390,7 @@ var customIdPipeline = {
5300
5390
  { customId: newValue },
5301
5391
  { autoSchedule: false, postProcessors: [] }
5302
5392
  );
5303
- },
5304
- trackEvent: "schedule_custom_id_edition"
5393
+ }
5305
5394
  };
5306
5395
 
5307
5396
  // src/columns/subcontract-id/subcontract-id-pipeline.ts
@@ -5440,6 +5529,9 @@ var ACTIVITY_BATCH_MODE = {
5440
5529
  APPEND: "append",
5441
5530
  REPLACE: "replace"
5442
5531
  };
5532
+ var ACTIVITY_PROGRESS_ORIGIN = {
5533
+ ACTION_BUTTON: "action-button"
5534
+ };
5443
5535
  var SCHEDULE_EFFECT_KIND = {
5444
5536
  SIR_AUTO_REJECT: "sir-auto-reject"
5445
5537
  };
@@ -5458,7 +5550,9 @@ var CHANGE_SET_SOURCE_KIND = {
5458
5550
 
5459
5551
  // src/dispatch/shared/constraint-warnings.ts
5460
5552
  function toConstraintWarning(activityId, notification) {
5461
- if (!notification || notification.type !== "constraint") return null;
5553
+ if (!notification || notification.type !== NOTIFICATION_TYPE.CONSTRAINT) {
5554
+ return null;
5555
+ }
5462
5556
  const data = notification.data;
5463
5557
  if (!data?.constraintType || !data.constraintDate) return null;
5464
5558
  return {
@@ -5504,6 +5598,7 @@ var ACTIVITY_PROPERTY = {
5504
5598
  TYPE: "type",
5505
5599
  START_DATE: "startDate",
5506
5600
  END_DATE: "endDate",
5601
+ DURATION_HOURS: "durationHours",
5507
5602
  CONSTRAINT_TYPE: "constraintType",
5508
5603
  CONSTRAINT_DATE: "constraintDate",
5509
5604
  PROGRESS: "progress",
@@ -5636,7 +5731,7 @@ async function buildActivityChanges(adapter, before, touched, correlativeBefore)
5636
5731
  function buildEntryForTouchedId(adapter, before, activityId, correlativeBefore) {
5637
5732
  const afterSnap = adapter.getActivity(activityId);
5638
5733
  if (!afterSnap) {
5639
- return { id: activityId, kind: "deleted", after: null };
5734
+ return { id: activityId, kind: ENTITY_CHANGE_KIND.DELETED, after: null };
5640
5735
  }
5641
5736
  const beforeSnap = before.get(activityId);
5642
5737
  if (!beforeSnap && correlativeBefore?.has(activityId)) {
@@ -5651,7 +5746,7 @@ function buildEntryForTouchedId(adapter, before, activityId, correlativeBefore)
5651
5746
  if (beforeSnap && Object.keys(diff).length === 0) return null;
5652
5747
  return {
5653
5748
  id: activityId,
5654
- kind: beforeSnap ? "updated" : "created",
5749
+ kind: beforeSnap ? ENTITY_CHANGE_KIND.UPDATED : ENTITY_CHANGE_KIND.CREATED,
5655
5750
  fields: diff,
5656
5751
  after: structuredCloneActivity(afterSnap)
5657
5752
  };
@@ -5660,7 +5755,7 @@ function buildCorrelativeOnlyEntry(activityId, correlativeIdBefore, liveActivity
5660
5755
  if (correlativeIdBefore === liveActivity.correlativeId) return null;
5661
5756
  return {
5662
5757
  id: activityId,
5663
- kind: "updated",
5758
+ kind: ENTITY_CHANGE_KIND.UPDATED,
5664
5759
  fields: {
5665
5760
  correlativeId: {
5666
5761
  before: correlativeIdBefore,
@@ -5785,7 +5880,7 @@ function expectedProgressFromBaseline(start, end, now, calendar) {
5785
5880
  }
5786
5881
 
5787
5882
  // src/columns/expected-progress/compute.ts
5788
- var isProject = (activity) => activity.type === "project";
5883
+ var isProject = (activity) => activity.type === ACTIVITY_TYPE.PROJECT;
5789
5884
  var leafExpectedLive = (activity, now, state) => {
5790
5885
  const calendarId = activity.calendarId;
5791
5886
  const calendar = calendarId != null ? state.calendarReader.getCalendar(String(calendarId)) : null;
@@ -5839,7 +5934,7 @@ function applyExpectedProgressLive(state, now) {
5839
5934
  }
5840
5935
 
5841
5936
  // src/columns/expected-progress-base/compute.ts
5842
- var isProject2 = (a) => a.type === "project";
5937
+ var isProject2 = (a) => a.type === ACTIVITY_TYPE.PROJECT;
5843
5938
  var activeBaselineOf = (a) => getActiveBaseline(a);
5844
5939
  var leafExpected = (a, now, adapter, defaultBaseCalendarId) => {
5845
5940
  const base = activeBaselineOf(a);
@@ -6001,15 +6096,44 @@ function getNextWorkingHour(activityParams) {
6001
6096
  return newDate;
6002
6097
  }
6003
6098
 
6099
+ // src/critical-path/legacy/constants/constraints.js
6100
+ var CONSTRAINT_TYPES = CONSTRAINT_TYPE;
6101
+
6102
+ // src/critical-path/legacy/constants/linkTypes.js
6103
+ var LINK_TYPES3 = Object.freeze({
6104
+ FS: LINK_CODE.FINISH_TO_START,
6105
+ SS: LINK_CODE.START_TO_START,
6106
+ FF: LINK_CODE.FINISH_TO_FINISH,
6107
+ SF: LINK_CODE.START_TO_FINISH
6108
+ });
6109
+
6110
+ // src/critical-path/legacy/constants/linkByCode.js
6111
+ function getLinkNameByCode(code) {
6112
+ return LINK_TYPE_CODE[String(Number(code))] ?? LINK_CODE.START_TO_FINISH;
6113
+ }
6114
+
6115
+ // src/critical-path/legacy/constants/calculation.js
6116
+ var CALCULATION_DIRECTION = Object.freeze({
6117
+ FORWARD: "forward",
6118
+ BACKWARD: "backward"
6119
+ });
6120
+ var COMPARISON_DIRECTION = Object.freeze({
6121
+ GREATER: "greater",
6122
+ LESS: "less"
6123
+ });
6124
+ var GANTT_FIELD = Object.freeze({
6125
+ SOURCE: "$source"
6126
+ });
6127
+
6004
6128
  // src/critical-path/legacy/helpers/filters.js
6005
6129
  var byFirstLevel = (activity) => {
6006
6130
  if (!activity) return false;
6007
6131
  return activity["$level"] === 1;
6008
6132
  };
6009
- var filterByParentType = (activity) => activity.type === "project";
6133
+ var filterByParentType = (activity) => activity.type === ACTIVITY_TYPE.PROJECT;
6010
6134
  var avoidSubproject = (activity) => activity["$level"] !== 0;
6011
- var byTaskType = (activity) => activity.type === "task";
6012
- var byTaskTypeAndMilestone = (activity) => activity.type === "task" || activity.type === "milestone";
6135
+ var byTaskType = (activity) => activity.type === ACTIVITY_TYPE.TASK;
6136
+ var byTaskTypeAndMilestone = (activity) => activity.type === ACTIVITY_TYPE.TASK || activity.type === ACTIVITY_TYPE.MILESTONE;
6013
6137
  var filters_default = {
6014
6138
  byFirstLevel,
6015
6139
  filterByParentType,
@@ -6018,37 +6142,6 @@ var filters_default = {
6018
6142
  byTaskTypeAndMilestone
6019
6143
  };
6020
6144
 
6021
- // src/critical-path/legacy/constants/constraints.js
6022
- var CONSTRAINT_TYPES = Object.freeze({
6023
- MFO: "mfo",
6024
- MSO: "mso",
6025
- FNLT: "fnlt",
6026
- FNET: "fnet",
6027
- SNET: "snet",
6028
- SNLT: "snlt",
6029
- ALAP: "alap",
6030
- ASAP: "asap"
6031
- });
6032
-
6033
- // src/critical-path/legacy/constants/linkTypes.js
6034
- var LINK_TYPES2 = Object.freeze({
6035
- FS: "fs",
6036
- SS: "ss",
6037
- FF: "ff",
6038
- SF: "sf"
6039
- });
6040
-
6041
- // src/critical-path/legacy/constants/linkByCode.js
6042
- function getLinkNameByCode(code) {
6043
- const linkMap = {
6044
- 0: "fs",
6045
- 1: "ss",
6046
- 2: "ff",
6047
- 3: "sf"
6048
- };
6049
- return linkMap[Number(code)] || "sf";
6050
- }
6051
-
6052
6145
  // src/critical-path/legacy/base/identifiers/secondLevelActivities.js
6053
6146
  function identifySecondLevelActivities(params) {
6054
6147
  const { gantt, pendingParentsWithNoLinks, calculations, linkProperty } = params;
@@ -6110,7 +6203,7 @@ function filterChildrenThatCanBeCalculated(params) {
6110
6203
  const linkedActivities = getArrayOfLinkedActivities3({
6111
6204
  gantt,
6112
6205
  links,
6113
- linkDirection: linkProperty === "$source" ? "target" : "source"
6206
+ linkDirection: linkProperty === GANTT_FIELD.SOURCE ? "target" : "source"
6114
6207
  });
6115
6208
  const isLinkedWithCalculatedOrSibling = linkedActivities.every(
6116
6209
  (linkedActivityId) => calculations.has(linkedActivityId)
@@ -6139,13 +6232,13 @@ function getArrayOfLinkedActivities(params) {
6139
6232
  function identifyInitialActivities({ gantt, linkProperty, direction }) {
6140
6233
  try {
6141
6234
  const chainStartActivities = getChainStartActivities(gantt, linkProperty);
6142
- if (direction === "forward") {
6235
+ if (direction === CALCULATION_DIRECTION.FORWARD) {
6143
6236
  return {
6144
6237
  chainStartActivities,
6145
6238
  activitiesStartChainButChildrenOfLinkedParents: null
6146
6239
  };
6147
6240
  }
6148
- if (direction === "backward") {
6241
+ if (direction === CALCULATION_DIRECTION.BACKWARD) {
6149
6242
  return processBackwardActivities(
6150
6243
  chainStartActivities,
6151
6244
  gantt,
@@ -6169,7 +6262,7 @@ function processBackwardActivities(chainStartActivities, gantt, linkProperty) {
6169
6262
  if (!parentActivity) return;
6170
6263
  if (parentActivity[linkProperty].length > 0) {
6171
6264
  activitiesStartChainButChildrenOfLinkedParents.add(activity.id);
6172
- } else if (parentActivity.constraint_type !== "fnlt") {
6265
+ } else if (parentActivity.constraint_type !== CONSTRAINT_TYPES.FNLT) {
6173
6266
  withoutLinkedParents.push(activity);
6174
6267
  }
6175
6268
  });
@@ -6190,7 +6283,7 @@ function identifyParentsWithAndWithoutLinks({
6190
6283
  const parentsWithFullProgress = /* @__PURE__ */ new Set();
6191
6284
  const pendingParentsWithNoLinks = /* @__PURE__ */ new Set();
6192
6285
  const pendingParentsWithLinks = /* @__PURE__ */ new Set();
6193
- if (direction === "backward") {
6286
+ if (direction === CALCULATION_DIRECTION.BACKWARD) {
6194
6287
  const parentsWithFullProgressArray = getParentsWithFullProgress(allParentActivities);
6195
6288
  parentsWithFullProgressArray.forEach((activity) => {
6196
6289
  parentsWithFullProgress.add(activity.id);
@@ -6228,9 +6321,9 @@ function getParentsWithNoLinks(activities, direction, linkProperty) {
6228
6321
  }
6229
6322
  const hasLinks = links.length > 0;
6230
6323
  const constraintType = activity.constraint_type || "";
6231
- const isNotFnlt = constraintType !== "fnlt";
6232
- if (direction === "forward") {
6233
- const isNotSnet = constraintType !== "snet";
6324
+ const isNotFnlt = constraintType !== CONSTRAINT_TYPES.FNLT;
6325
+ if (direction === CALCULATION_DIRECTION.FORWARD) {
6326
+ const isNotSnet = constraintType !== CONSTRAINT_TYPES.SNET;
6234
6327
  return !hasLinks && isNotFnlt && isNotSnet;
6235
6328
  } else {
6236
6329
  return !hasLinks && isNotFnlt;
@@ -6286,10 +6379,10 @@ function identifyForbiddenActivities({
6286
6379
  }
6287
6380
  }
6288
6381
  function getLinkProperty(direction) {
6289
- return direction === "forward" ? "$source" : "$target";
6382
+ return direction === CALCULATION_DIRECTION.FORWARD ? GANTT_FIELD.SOURCE : "$target";
6290
6383
  }
6291
6384
  function getLinkDirection(direction) {
6292
- return direction === "forward" ? "target" : "source";
6385
+ return direction === CALCULATION_DIRECTION.FORWARD ? "target" : "source";
6293
6386
  }
6294
6387
  function getArrayOfLinkedActivities2(gantt, links, direction) {
6295
6388
  return links.map((link) => {
@@ -6325,7 +6418,7 @@ function mutateDate({
6325
6418
  activityCalendar,
6326
6419
  activity
6327
6420
  }) {
6328
- if (linkType2 === LINK_TYPES2.FS && lag === 0) {
6421
+ if (linkType2 === LINK_TYPES3.FS && lag === 0) {
6329
6422
  return getNextWorkingHour({
6330
6423
  activityCalendar,
6331
6424
  direction: "future",
@@ -6361,10 +6454,10 @@ function calculateRestrictionSnet({
6361
6454
  return { es, ef };
6362
6455
  }
6363
6456
  function mutateTheDateToFutureOrPastInBaseRestriction(dateBaseToCalculate, restrictionOfLink, activityCalendar, activity) {
6364
- if (![LINK_TYPES2.FS, LINK_TYPES2.SS, LINK_TYPES2.FF].includes(restrictionOfLink)) {
6457
+ if (![LINK_TYPES3.FS, LINK_TYPES3.SS, LINK_TYPES3.FF].includes(restrictionOfLink)) {
6365
6458
  return dateBaseToCalculate;
6366
6459
  }
6367
- let constraintThatGoToNextWorkingHour = [LINK_TYPES2.FS, LINK_TYPES2.SS];
6460
+ let constraintThatGoToNextWorkingHour = [LINK_TYPES3.FS, LINK_TYPES3.SS];
6368
6461
  let direction = constraintThatGoToNextWorkingHour.includes(restrictionOfLink) ? "future" : "past";
6369
6462
  return getNextWorkingHour({
6370
6463
  dateBaseToCalculate,
@@ -6392,10 +6485,10 @@ var CalculateForwardParentsWithLinks = class {
6392
6485
  const calculationsFromLinks = this.calculateLinks();
6393
6486
  const maxEfFromLinks = getMaxEarlyStartSet(calculationsFromLinks);
6394
6487
  const constraintType = this.activity.constraint_type;
6395
- if (constraintType === "snet") {
6488
+ if (constraintType === CONSTRAINT_TYPES.SNET) {
6396
6489
  return this.handleSNETConstraint(maxEfFromLinks);
6397
6490
  }
6398
- if (constraintType === "fnlt") {
6491
+ if (constraintType === CONSTRAINT_TYPES.FNLT) {
6399
6492
  return this.handleFNLTConstraint(maxEfFromLinks);
6400
6493
  }
6401
6494
  return maxEfFromLinks;
@@ -6409,13 +6502,13 @@ var CalculateForwardParentsWithLinks = class {
6409
6502
  const predecessorEs = linkedActivity.es;
6410
6503
  const predecessorEf = linkedActivity.ef;
6411
6504
  let calculation = null;
6412
- if (linkType2 === "ss") {
6505
+ if (linkType2 === LINK_TYPES3.SS) {
6413
6506
  calculation = this.calculateSSLink({ lag, predecessorEs });
6414
- } else if (linkType2 === "ff") {
6507
+ } else if (linkType2 === LINK_TYPES3.FF) {
6415
6508
  calculation = this.calculateFFLink({ lag, predecessorEf });
6416
- } else if (linkType2 === "fs") {
6509
+ } else if (linkType2 === LINK_TYPES3.FS) {
6417
6510
  calculation = this.calculateFSLink({ lag, predecessorEf });
6418
- } else if (linkType2 === "sf") {
6511
+ } else if (linkType2 === LINK_TYPES3.SF) {
6419
6512
  calculation = this.calculateSFLink({
6420
6513
  lag,
6421
6514
  predecessorEs,
@@ -6460,7 +6553,7 @@ var CalculateForwardParentsWithLinks = class {
6460
6553
  }
6461
6554
  calculateSSLink({ lag, predecessorEs }) {
6462
6555
  const esLinked = mutateDate({
6463
- linkType: "ss",
6556
+ linkType: LINK_TYPES3.SS,
6464
6557
  lag,
6465
6558
  predecessorTime: predecessorEs,
6466
6559
  activityCalendar: this.activityCalendar,
@@ -6475,7 +6568,7 @@ var CalculateForwardParentsWithLinks = class {
6475
6568
  if (lag > 0) {
6476
6569
  es = mutateTheDateToFutureOrPastInBaseRestriction(
6477
6570
  es,
6478
- "ss",
6571
+ LINK_TYPES3.SS,
6479
6572
  this.activityCalendar,
6480
6573
  this.activity
6481
6574
  );
@@ -6490,7 +6583,7 @@ var CalculateForwardParentsWithLinks = class {
6490
6583
  }
6491
6584
  calculateFFLink({ lag, predecessorEf }) {
6492
6585
  const efLinked = mutateDate({
6493
- linkType: "ff",
6586
+ linkType: LINK_TYPES3.FF,
6494
6587
  lag,
6495
6588
  predecessorTime: predecessorEf,
6496
6589
  activityCalendar: this.activityCalendar,
@@ -6511,7 +6604,7 @@ var CalculateForwardParentsWithLinks = class {
6511
6604
  if (lag > 0) {
6512
6605
  es = mutateTheDateToFutureOrPastInBaseRestriction(
6513
6606
  es,
6514
- "ff",
6607
+ LINK_TYPES3.FF,
6515
6608
  this.activityCalendar,
6516
6609
  this.activity
6517
6610
  );
@@ -6558,7 +6651,7 @@ var CalculateForwardParentsWithLinks = class {
6558
6651
  if (lag > 0) {
6559
6652
  es = mutateTheDateToFutureOrPastInBaseRestriction(
6560
6653
  es,
6561
- "sf",
6654
+ LINK_TYPES3.SF,
6562
6655
  this.activityCalendar,
6563
6656
  this.activity
6564
6657
  );
@@ -6585,16 +6678,16 @@ var CalculateBackwardParentsLinks = class {
6585
6678
  const calculationsFromLinks = [];
6586
6679
  for (let linkedActivity of this.linkedActivitiesData) {
6587
6680
  const linkType2 = getLinkNameByCode(linkedActivity.linkType);
6588
- if (linkedActivity.type === "task" && Number(linkedActivity.progress) > 0) {
6681
+ if (linkedActivity.type === ACTIVITY_TYPE.TASK && Number(linkedActivity.progress) > 0) {
6589
6682
  continue;
6590
6683
  }
6591
- if (linkedActivity.type === "project" && Number(linkedActivity.progress) === 100) {
6684
+ if (linkedActivity.type === ACTIVITY_TYPE.PROJECT && Number(linkedActivity.progress) === 100) {
6592
6685
  continue;
6593
6686
  }
6594
6687
  const lag = linkedActivity.linkLag;
6595
6688
  let sucessorLs = linkedActivity.ls;
6596
6689
  let sucessorLf = linkedActivity.lf;
6597
- if (linkType2 === "ss") {
6690
+ if (linkType2 === LINK_TYPES3.SS) {
6598
6691
  const valuesToDoCalculation = {
6599
6692
  lag,
6600
6693
  workTime: sucessorLs,
@@ -6604,7 +6697,7 @@ var CalculateBackwardParentsLinks = class {
6604
6697
  let { ls, lf } = this.calculateSSLink(valuesToDoCalculation);
6605
6698
  calculationsFromLinks.push({ ls, lf });
6606
6699
  }
6607
- if (linkType2 === "ff") {
6700
+ if (linkType2 === LINK_TYPES3.FF) {
6608
6701
  const valuesToDoCalculation = {
6609
6702
  lag,
6610
6703
  workTime: sucessorLf,
@@ -6614,7 +6707,7 @@ var CalculateBackwardParentsLinks = class {
6614
6707
  let { ls, lf } = this.calculateFFLink(valuesToDoCalculation);
6615
6708
  calculationsFromLinks.push({ ls, lf });
6616
6709
  }
6617
- if (linkType2 === "fs") {
6710
+ if (linkType2 === LINK_TYPES3.FS) {
6618
6711
  const valuesToDoCalculation = {
6619
6712
  lag,
6620
6713
  workTime: sucessorLs,
@@ -6624,7 +6717,7 @@ var CalculateBackwardParentsLinks = class {
6624
6717
  let { ls, lf } = this.calculateFsLink(valuesToDoCalculation);
6625
6718
  calculationsFromLinks.push({ ls, lf });
6626
6719
  }
6627
- if (linkType2 === "sf") {
6720
+ if (linkType2 === LINK_TYPES3.SF) {
6628
6721
  const valuesToDoCalculation = {
6629
6722
  lag,
6630
6723
  workTime: sucessorLf,
@@ -6635,7 +6728,7 @@ var CalculateBackwardParentsLinks = class {
6635
6728
  calculationsFromLinks.push({ ls, lf });
6636
6729
  }
6637
6730
  }
6638
- if (this.activity.constraint_type === "fnlt") {
6731
+ if (this.activity.constraint_type === CONSTRAINT_TYPES.FNLT) {
6639
6732
  const maxLfFromLinks = this.getMinLfFromLinks(calculationsFromLinks);
6640
6733
  let restriction = this.calculateSfRestrictionDates();
6641
6734
  if (!maxLfFromLinks) {
@@ -6682,7 +6775,7 @@ var CalculateBackwardParentsLinks = class {
6682
6775
  lfSucessor = this.getLastWorkingHour(
6683
6776
  lfSucessor,
6684
6777
  this.activityCalendar,
6685
- "past"
6778
+ WORK_TIME_DIRECTION.PAST
6686
6779
  );
6687
6780
  }
6688
6781
  lfPred = addDurationToDate(
@@ -6712,7 +6805,7 @@ var CalculateBackwardParentsLinks = class {
6712
6805
  const lsSucessor2 = this.getLastWorkingHour(
6713
6806
  workTime,
6714
6807
  this.activityCalendar,
6715
- "past"
6808
+ WORK_TIME_DIRECTION.PAST
6716
6809
  );
6717
6810
  lfPred = addDurationToDate(
6718
6811
  this.activityCalendar,
@@ -6720,7 +6813,7 @@ var CalculateBackwardParentsLinks = class {
6720
6813
  lfDataCalculation,
6721
6814
  this.activity
6722
6815
  );
6723
- lfPred = this.getLastWorkingHour(lfPred, this.activityCalendar, "past");
6816
+ lfPred = this.getLastWorkingHour(lfPred, this.activityCalendar, WORK_TIME_DIRECTION.PAST);
6724
6817
  lsPred = addDurationToDate(
6725
6818
  this.activityCalendar,
6726
6819
  lfPred,
@@ -6746,7 +6839,7 @@ var CalculateBackwardParentsLinks = class {
6746
6839
  this.activity
6747
6840
  );
6748
6841
  if (!isMilestone) {
6749
- lfPred = this.getLastWorkingHour(lfPred, this.activityCalendar, "past");
6842
+ lfPred = this.getLastWorkingHour(lfPred, this.activityCalendar, WORK_TIME_DIRECTION.PAST);
6750
6843
  }
6751
6844
  return { ls: lsPred, lf: lfPred };
6752
6845
  }
@@ -6833,10 +6926,10 @@ var CalculateBackwardParentsLinks = class {
6833
6926
  );
6834
6927
  return { ls: lsRestriction, lf: lfRestriction };
6835
6928
  }
6836
- getLastWorkingHour(date2, activityCalendar, dir = "past") {
6929
+ getLastWorkingHour(date2, activityCalendar, dir = WORK_TIME_DIRECTION.PAST) {
6837
6930
  const normalizedDate = date2 instanceof Date ? date2 : new Date(date2);
6838
6931
  let resetedDate = moment_default(normalizedDate).clone();
6839
- if (this.isActivityInInitHour(activityCalendar, normalizedDate) && dir === "past") {
6932
+ if (this.isActivityInInitHour(activityCalendar, normalizedDate) && dir === WORK_TIME_DIRECTION.PAST) {
6840
6933
  resetedDate = resetedDate.hours(0).minutes(0).seconds(0).milliseconds(0);
6841
6934
  }
6842
6935
  let newDate = getNextWorkingHour({
@@ -6882,7 +6975,7 @@ function parentWithLinks(params) {
6882
6975
  const linksArray = parent[linkProperty];
6883
6976
  const parentData = extractParentData(parent);
6884
6977
  let calculation = null;
6885
- if (direction === "forward") {
6978
+ if (direction === CALCULATION_DIRECTION.FORWARD) {
6886
6979
  const linksWithActivityData = getLinksWithActivityDataForward(
6887
6980
  linksArray,
6888
6981
  linkDirection,
@@ -7000,7 +7093,7 @@ function getCalculatedChildren(childrenIds, calculations) {
7000
7093
  return childrenIds.filter((childId) => calculations.has(childId)).map((childId) => calculations.get(childId));
7001
7094
  }
7002
7095
  function computeParentCalculation(childrenCalculations, direction) {
7003
- if (direction === "forward") {
7096
+ if (direction === CALCULATION_DIRECTION.FORWARD) {
7004
7097
  const earliestStart = calculateEarliestDate(childrenCalculations, "es");
7005
7098
  const latestFinish = calculateLatestDate(childrenCalculations, "ef");
7006
7099
  return { es: earliestStart, ef: latestFinish };
@@ -7032,8 +7125,8 @@ var CalculationOfParent = class {
7032
7125
  constructor(params) {
7033
7126
  this.activity = params.activity;
7034
7127
  this.direction = params.direction;
7035
- this.linkProperty = params.direction === "forward" ? "$target" : "$source";
7036
- this.linkDirection = params.direction === "forward" ? "source" : "target";
7128
+ this.linkProperty = params.direction === CALCULATION_DIRECTION.FORWARD ? "$target" : GANTT_FIELD.SOURCE;
7129
+ this.linkDirection = params.direction === CALCULATION_DIRECTION.FORWARD ? "source" : "target";
7037
7130
  this.calculationsOfParentThatImpactChildrens = params.calculationsOfParentThatImpactChildrens;
7038
7131
  this.calculations = params.calculations;
7039
7132
  this.calculationOfParentsFromLinks = params.calculationOfParentsFromLinks;
@@ -7047,7 +7140,7 @@ var CalculationOfParent = class {
7047
7140
  const allLinkedTasks = this.getArrayOfIdOfLinkedActivities(
7048
7141
  this.activity[this.linkProperty]
7049
7142
  );
7050
- if (this.direction === "backward") {
7143
+ if (this.direction === CALCULATION_DIRECTION.BACKWARD) {
7051
7144
  const restrictions = [CONSTRAINT_TYPES.FNLT];
7052
7145
  if (this.shouldCalculateParentWithLinksBackward(restrictions)) {
7053
7146
  this.calculateAndStoreParentWithLinks(this.activity);
@@ -7060,10 +7153,10 @@ var CalculationOfParent = class {
7060
7153
  }
7061
7154
  const areAllLinksCalculated = this.areAllLinksCalculated(allLinkedTasks);
7062
7155
  if (areAllLinksCalculated && this.calculationsOfParentThatImpactChildrens.has(this.activity.id)) {
7063
- if (this.direction === "forward") {
7156
+ if (this.direction === CALCULATION_DIRECTION.FORWARD) {
7064
7157
  this.setDatesToParentsWithLinks();
7065
7158
  }
7066
- if (this.direction === "backward") {
7159
+ if (this.direction === CALCULATION_DIRECTION.BACKWARD) {
7067
7160
  this.setDatesToParentsWithLinksBackward();
7068
7161
  }
7069
7162
  return;
@@ -7264,7 +7357,7 @@ var ThirdLevelActivityIdentifier = class {
7264
7357
  this.addActivityToLevel(activity, activitiesByLevel);
7265
7358
  }
7266
7359
  isProjectActivity(activity) {
7267
- return activity.type === "project";
7360
+ return activity.type === ACTIVITY_TYPE.PROJECT;
7268
7361
  }
7269
7362
  hasLink(activity) {
7270
7363
  return Boolean(activity[this.linkProperty]?.length);
@@ -7333,8 +7426,8 @@ var CriticalPathHelpers = class {
7333
7426
  constructor(ganttInstace, direction) {
7334
7427
  this.direction = direction;
7335
7428
  this.gantt = ganttInstace;
7336
- this.linkProperty = this.direction === "forward" ? "$target" : "$source";
7337
- this.linkDirection = this.direction === "forward" ? "source" : "target";
7429
+ this.linkProperty = this.direction === CALCULATION_DIRECTION.FORWARD ? "$target" : GANTT_FIELD.SOURCE;
7430
+ this.linkDirection = this.direction === CALCULATION_DIRECTION.FORWARD ? "source" : "target";
7338
7431
  this.projectDates = ganttInstace.getSubtaskDates();
7339
7432
  }
7340
7433
  tryToCalculateLastLevelChildrens() {
@@ -7426,7 +7519,7 @@ var CriticalPathHelpers = class {
7426
7519
  function(activity) {
7427
7520
  const parentId = Number(activity.parent);
7428
7521
  allTasks.add(activity.id);
7429
- if (activity.type === "project") {
7522
+ if (activity.type === ACTIVITY_TYPE.PROJECT) {
7430
7523
  const parentInfo = {
7431
7524
  level: activity["$level"],
7432
7525
  hasLink: Boolean(activity[this.linkProperty].length),
@@ -7447,7 +7540,7 @@ var CriticalPathHelpers = class {
7447
7540
  }
7448
7541
  level.get(Number(activity.parent)).push({
7449
7542
  id: activity.id,
7450
- isParent: activity.type === "project",
7543
+ isParent: activity.type === ACTIVITY_TYPE.PROJECT,
7451
7544
  calculated: false
7452
7545
  });
7453
7546
  }.bind(this),
@@ -7497,7 +7590,7 @@ var CriticalPathHelpers = class {
7497
7590
  }
7498
7591
  calculateSecondLevelActivities() {
7499
7592
  try {
7500
- if (this.direction === "forward") {
7593
+ if (this.direction === CALCULATION_DIRECTION.FORWARD) {
7501
7594
  this.recursiveCalculateEfAndEs(
7502
7595
  Array.from(this.secondLevelActivities),
7503
7596
  0,
@@ -7515,12 +7608,12 @@ var CriticalPathHelpers = class {
7515
7608
  this.chainStartActivities.forEach((activity) => {
7516
7609
  if (!activity) return;
7517
7610
  if (activity.progress > 100) return;
7518
- if (activity.type === "project") return;
7611
+ if (activity.type === ACTIVITY_TYPE.PROJECT) return;
7519
7612
  const dates = this.calculateStartAndFinishOfChainOrigin(
7520
7613
  activity,
7521
7614
  this.direction
7522
7615
  );
7523
- if (this.direction === "forward") {
7616
+ if (this.direction === CALCULATION_DIRECTION.FORWARD) {
7524
7617
  let { es, ef } = dates;
7525
7618
  this.calculations.set(activity.id, { es, ef, text: activity.text });
7526
7619
  this.activitiesWaitingForCalculation.delete(activity.id);
@@ -7601,7 +7694,7 @@ var CriticalPathHelpers = class {
7601
7694
  );
7602
7695
  }
7603
7696
  let direction = customDirection || this.direction;
7604
- if (direction === "forward") {
7697
+ if (direction === CALCULATION_DIRECTION.FORWARD) {
7605
7698
  let es = activity.start_date;
7606
7699
  let ef = activity.end_date;
7607
7700
  return {
@@ -7712,14 +7805,14 @@ var CriticalPathHelpers = class {
7712
7805
  }
7713
7806
  );
7714
7807
  arrayOfActivitiesObject.forEach((activity) => {
7715
- const isAParent = activity.type === "project";
7808
+ const isAParent = activity.type === ACTIVITY_TYPE.PROJECT;
7716
7809
  this.setDatesForActivityWithFullProgress(activity);
7717
7810
  this.activitiesWaitingForCalculation.delete(activity.id);
7718
7811
  if (isAParent && this.pendingParentsWithLinks.has(activity.id)) {
7719
7812
  this.parentCalculationFromChildren.add(activity.id);
7720
7813
  this.calculationsOfParentThatImpactChildrens.set(activity.id, {
7721
- [this.direction === "forward" ? "es" : "ls"]: activity.start_date,
7722
- [this.direction === "forward" ? "ef" : "lf"]: activity.end_date
7814
+ [this.direction === CALCULATION_DIRECTION.FORWARD ? "es" : "ls"]: activity.start_date,
7815
+ [this.direction === CALCULATION_DIRECTION.FORWARD ? "ef" : "lf"]: activity.end_date
7723
7816
  });
7724
7817
  this.calculationOfParentsFromLinks.add(activity.id);
7725
7818
  }
@@ -7814,7 +7907,7 @@ var LinksRulesCalculationsMethods = class {
7814
7907
  }
7815
7908
  return this.calculatedActivities.get(Number(activity));
7816
7909
  }
7817
- calculateSucessorTimes(predecessorTime, esDataCalculation, efDataCalculation = 0, lag, restrictionOfLink = LINK_TYPES2.FS) {
7910
+ calculateSucessorTimes(predecessorTime, esDataCalculation, efDataCalculation = 0, lag, restrictionOfLink = LINK_TYPES3.FS) {
7818
7911
  const activityCalendar = this.gantt.getCalendar(
7819
7912
  this.referenceActivity.calendar_id
7820
7913
  );
@@ -7826,9 +7919,9 @@ var LinksRulesCalculationsMethods = class {
7826
7919
  let dateBaseToCalculate = predecessorTime;
7827
7920
  let es = null;
7828
7921
  let ef = null;
7829
- const isAMilestone = this.referenceActivity.type === "milestone";
7922
+ const isAMilestone = this.referenceActivity.type === ACTIVITY_TYPE.MILESTONE;
7830
7923
  if (!isAMilestone) {
7831
- if (restrictionOfLink === LINK_TYPES2.FS && lag === 0) {
7924
+ if (restrictionOfLink === LINK_TYPES3.FS && lag === 0) {
7832
7925
  dateBaseToCalculate = getNextWorkingHour({
7833
7926
  dateBaseToCalculate,
7834
7927
  activityCalendar,
@@ -7843,7 +7936,7 @@ var LinksRulesCalculationsMethods = class {
7843
7936
  );
7844
7937
  }
7845
7938
  }
7846
- if ([LINK_TYPES2.FF, LINK_TYPES2.SF].includes(restrictionOfLink)) {
7939
+ if ([LINK_TYPES3.FF, LINK_TYPES3.SF].includes(restrictionOfLink)) {
7847
7940
  ef = addDurationToDate(
7848
7941
  activityCalendar,
7849
7942
  dateBaseToCalculate,
@@ -7897,7 +7990,7 @@ var LinksRulesCalculationsMethods = class {
7897
7990
  esDataCalculation,
7898
7991
  efDataCalculation,
7899
7992
  lag,
7900
- LINK_TYPES2.SS
7993
+ LINK_TYPES3.SS
7901
7994
  );
7902
7995
  }
7903
7996
  calculateFF(link) {
@@ -7911,7 +8004,7 @@ var LinksRulesCalculationsMethods = class {
7911
8004
  esDataCalculation,
7912
8005
  efDataCalculation,
7913
8006
  lag,
7914
- LINK_TYPES2.FF
8007
+ LINK_TYPES3.FF
7915
8008
  );
7916
8009
  }
7917
8010
  calculateFS(link) {
@@ -7925,7 +8018,7 @@ var LinksRulesCalculationsMethods = class {
7925
8018
  esDataCalculation,
7926
8019
  efDataCalculation,
7927
8020
  lag,
7928
- LINK_TYPES2.FS
8021
+ LINK_TYPES3.FS
7929
8022
  );
7930
8023
  }
7931
8024
  calculateSF(link) {
@@ -7939,17 +8032,17 @@ var LinksRulesCalculationsMethods = class {
7939
8032
  esDataCalculation,
7940
8033
  efDataCalculation,
7941
8034
  lag,
7942
- LINK_TYPES2.SF
8035
+ LINK_TYPES3.SF
7943
8036
  );
7944
8037
  }
7945
8038
  mutateTheDateToFutureOrPastInBaseRestriction(dateBaseToCalculate, restrictionOfLink, activityCalendar) {
7946
- if (![LINK_TYPES2.FS, LINK_TYPES2.SS, LINK_TYPES2.FF].includes(restrictionOfLink)) {
8039
+ if (![LINK_TYPES3.FS, LINK_TYPES3.SS, LINK_TYPES3.FF].includes(restrictionOfLink)) {
7947
8040
  return dateBaseToCalculate;
7948
8041
  }
7949
- const constraintThatGoToNextWorkingHour = [LINK_TYPES2.FS, LINK_TYPES2.SS];
8042
+ const constraintThatGoToNextWorkingHour = [LINK_TYPES3.FS, LINK_TYPES3.SS];
7950
8043
  const direction = constraintThatGoToNextWorkingHour.includes(
7951
8044
  restrictionOfLink
7952
- ) ? "future" : "past";
8045
+ ) ? "future" : WORK_TIME_DIRECTION.PAST;
7953
8046
  return getNextWorkingHour({
7954
8047
  dateBaseToCalculate,
7955
8048
  activityCalendar,
@@ -8030,7 +8123,7 @@ var ActivityCalculator = class {
8030
8123
  const pendingActivities = new Set(pendingToCalculate);
8031
8124
  for (const activityId of pendingToCalculate) {
8032
8125
  const activityData = this.gantt.getTask(activityId);
8033
- if (activityData.type === "project") {
8126
+ if (activityData.type === ACTIVITY_TYPE.PROJECT) {
8034
8127
  this.handleProjectActivity(
8035
8128
  activityId,
8036
8129
  activityData,
@@ -8094,7 +8187,7 @@ var ActivityCalculator = class {
8094
8187
  canCalculateParentActivity(activityData) {
8095
8188
  const hasNoLinks = (activityData[this.linkProperty] || []).length === 0;
8096
8189
  const constraintType = activityData.constraint_type;
8097
- const isSpecialConstraintType = this.direction === "forward" ? constraintType === "fnlt" || constraintType === "snlt" : constraintType === "fnlt";
8190
+ const isSpecialConstraintType = this.direction === CALCULATION_DIRECTION.FORWARD ? constraintType === CONSTRAINT_TYPES.FNLT || constraintType === CONSTRAINT_TYPES.SNLT : constraintType === CONSTRAINT_TYPES.FNLT;
8098
8191
  if (isSpecialConstraintType && hasNoLinks) {
8099
8192
  return true;
8100
8193
  }
@@ -8112,13 +8205,13 @@ var ActivityCalculator = class {
8112
8205
  if (isParentPendingWithLinks && !hasParentCalculationFromLinks) {
8113
8206
  return;
8114
8207
  }
8115
- if (this.direction === "backward") {
8208
+ if (this.direction === CALCULATION_DIRECTION.BACKWARD) {
8116
8209
  const isStartChainChildOfLinkedParent = this.activitiesStartChainButChildrenOfLinkedParents.has(activityId);
8117
8210
  if (isStartChainChildOfLinkedParent && !hasParentCalculationFromLinks) {
8118
8211
  return;
8119
8212
  }
8120
8213
  }
8121
- if (activityData["$target"].length === 0 && activityData["$source"].length === 0) {
8214
+ if (activityData["$target"].length === 0 && activityData[GANTT_FIELD.SOURCE].length === 0) {
8122
8215
  activitiesThatCanBeCalculated.add(activityId);
8123
8216
  pendingActivities.delete(activityId);
8124
8217
  return;
@@ -8129,7 +8222,7 @@ var ActivityCalculator = class {
8129
8222
  const arePredecessorsCalculated = linkedActivities.every(
8130
8223
  (act) => this.calculations.has(act.id)
8131
8224
  );
8132
- if (this.direction === "backward") {
8225
+ if (this.direction === CALCULATION_DIRECTION.BACKWARD) {
8133
8226
  const hasNoLinkedActivities = linkedActivities.length === 0;
8134
8227
  if ((hasNoLinkedActivities || arePredecessorsCalculated) && hasParentCalculationFromLinks) {
8135
8228
  activitiesThatCanBeCalculated.add(activityId);
@@ -8181,7 +8274,7 @@ var get_activities_to_calculate_default = ActivityCalculator;
8181
8274
  var createIsCurrent2 = (calculationId, getCurrentId) => () => getCurrentId() === calculationId;
8182
8275
 
8183
8276
  // src/critical-path/legacy/utils/validation.js
8184
- var shouldAbortCalculation = (gantt) => !gantt?.fullyParsed || typeof window !== "undefined" && window.to_use_react_gantt?.conversionMode?.isActive;
8277
+ var shouldAbortCalculation = (gantt) => !gantt?.fullyParsed;
8185
8278
 
8186
8279
  // src/critical-path/legacy/utils/timing.js
8187
8280
  var TIME_BUDGET_MS = 16;
@@ -8232,7 +8325,7 @@ var iterativeCalculate = async ({
8232
8325
  // src/critical-path/legacy/forward-path/index.js
8233
8326
  var ForwardPath = class extends generic_calculations_default {
8234
8327
  constructor(gantt) {
8235
- super(gantt, "forward");
8328
+ super(gantt, CALCULATION_DIRECTION.FORWARD);
8236
8329
  this.gantt = gantt;
8237
8330
  this.chainStartActivities = /* @__PURE__ */ new Set();
8238
8331
  this.secondLevelActivities = /* @__PURE__ */ new Set();
@@ -8297,7 +8390,7 @@ var ForwardPath = class extends generic_calculations_default {
8297
8390
  calculateStartAndFinishTimes(activitiesToCalculate) {
8298
8391
  activitiesToCalculate.forEach((activity) => {
8299
8392
  const activityReference = this.gantt.getTask(activity);
8300
- if (activityReference.type === "project") {
8393
+ if (activityReference.type === ACTIVITY_TYPE.PROJECT) {
8301
8394
  return this.doCalculationForParentType(activityReference);
8302
8395
  }
8303
8396
  if (!activityReference) {
@@ -8416,11 +8509,11 @@ var ForwardPath = class extends generic_calculations_default {
8416
8509
  this.activitiesWaitingForCalculation.delete(activity);
8417
8510
  });
8418
8511
  }
8419
- getTheGreatesDateBetweenRestrictionAndEsEf(restriction, linkCalculation, comparisonType = "greater") {
8420
- if (comparisonType === "greater") {
8512
+ getTheGreatesDateBetweenRestrictionAndEsEf(restriction, linkCalculation, comparisonType = COMPARISON_DIRECTION.GREATER) {
8513
+ if (comparisonType === COMPARISON_DIRECTION.GREATER) {
8421
8514
  return linkCalculation.ef > restriction.ef ? linkCalculation : restriction;
8422
8515
  }
8423
- if (comparisonType === "less") {
8516
+ if (comparisonType === COMPARISON_DIRECTION.LESS) {
8424
8517
  return linkCalculation.ef < restriction.ef ? linkCalculation : restriction;
8425
8518
  }
8426
8519
  }
@@ -8440,7 +8533,7 @@ var ForwardPath = class extends generic_calculations_default {
8440
8533
  const comparisontype = [
8441
8534
  CONSTRAINT_TYPES.SNET,
8442
8535
  CONSTRAINT_TYPES.FNET
8443
- ].includes(constraintType) ? "greater" : "less";
8536
+ ].includes(constraintType) ? COMPARISON_DIRECTION.GREATER : COMPARISON_DIRECTION.LESS;
8444
8537
  const { es, ef } = this.getTheGreatesDateBetweenRestrictionAndEsEf(
8445
8538
  calculatedRestriction,
8446
8539
  calculatedEsEf,
@@ -8456,9 +8549,9 @@ var ForwardPath = class extends generic_calculations_default {
8456
8549
  }
8457
8550
  const sourceId = ganttActivityLink.source;
8458
8551
  const targetId = ganttActivityLink.target;
8459
- if (!this.gantt.getTask(sourceId) || this.gantt.getTask(sourceId)?.type === "project")
8552
+ if (!this.gantt.getTask(sourceId) || this.gantt.getTask(sourceId)?.type === ACTIVITY_TYPE.PROJECT)
8460
8553
  return;
8461
- if (!this.gantt.getTask(targetId) || this.gantt.getTask(targetId)?.type === "project")
8554
+ if (!this.gantt.getTask(targetId) || this.gantt.getTask(targetId)?.type === ACTIVITY_TYPE.PROJECT)
8462
8555
  return;
8463
8556
  return link;
8464
8557
  }).filter(Boolean);
@@ -8481,7 +8574,7 @@ var CalculationsGenericMethods = class {
8481
8574
  }
8482
8575
  return this.calculatedActivities.get(activity);
8483
8576
  }
8484
- calculateSuccessorTimes(sucessorTime, lsDataCalculation, lfDataCalculation = 0, lag, type = LINK_TYPES2.FS) {
8577
+ calculateSuccessorTimes(sucessorTime, lsDataCalculation, lfDataCalculation = 0, lag, type = LINK_TYPES3.FS) {
8485
8578
  let activityCalendar = this.gantt.getCalendar(this.activity.calendar_id);
8486
8579
  if (!activityCalendar) {
8487
8580
  throw new Error(
@@ -8489,7 +8582,7 @@ var CalculationsGenericMethods = class {
8489
8582
  );
8490
8583
  }
8491
8584
  const workTime = sucessorTime;
8492
- let isMilestone = this.activity.type === "milestone";
8585
+ let isMilestone = this.activity.type === ACTIVITY_TYPE.MILESTONE;
8493
8586
  if (isMilestone && lag === 0) {
8494
8587
  let lsPred = addDurationToDate(
8495
8588
  activityCalendar,
@@ -8513,19 +8606,19 @@ var CalculationsGenericMethods = class {
8513
8606
  lfDataCalculation,
8514
8607
  isMilestone
8515
8608
  };
8516
- if (type === LINK_TYPES2.FS) {
8609
+ if (type === LINK_TYPES3.FS) {
8517
8610
  let { ls, lf } = this.calculateFsLink(valuesToDoCalculation);
8518
8611
  return { ls, lf };
8519
8612
  }
8520
- if (type === LINK_TYPES2.FF) {
8613
+ if (type === LINK_TYPES3.FF) {
8521
8614
  let { ls, lf } = this.calculateFFLink(valuesToDoCalculation);
8522
8615
  return { ls, lf };
8523
8616
  }
8524
- if (type === LINK_TYPES2.SS) {
8617
+ if (type === LINK_TYPES3.SS) {
8525
8618
  let { ls, lf } = this.calculateSSlink(valuesToDoCalculation);
8526
8619
  return { ls, lf };
8527
8620
  }
8528
- if (type === LINK_TYPES2.SF) {
8621
+ if (type === LINK_TYPES3.SF) {
8529
8622
  let { ls, lf } = this.calculateSFLink(valuesToDoCalculation);
8530
8623
  return { ls, lf };
8531
8624
  }
@@ -8540,7 +8633,7 @@ var CalculationsGenericMethods = class {
8540
8633
  lsDataForCalculation,
8541
8634
  lfDataForCalculation,
8542
8635
  lag,
8543
- LINK_TYPES2.SS
8636
+ LINK_TYPES3.SS
8544
8637
  );
8545
8638
  }
8546
8639
  calculateFF(link, constraint) {
@@ -8557,7 +8650,7 @@ var CalculationsGenericMethods = class {
8557
8650
  lsDataForCalculation,
8558
8651
  lfDataForCalculation,
8559
8652
  lag,
8560
- LINK_TYPES2.FF
8653
+ LINK_TYPES3.FF
8561
8654
  );
8562
8655
  }
8563
8656
  calculateFS(link, constraint) {
@@ -8575,7 +8668,7 @@ var CalculationsGenericMethods = class {
8575
8668
  lsDataForCalculation,
8576
8669
  lfDataForCalculation,
8577
8670
  lag,
8578
- LINK_TYPES2.FS
8671
+ LINK_TYPES3.FS
8579
8672
  );
8580
8673
  }
8581
8674
  calculateSF(link, getFromForward = false) {
@@ -8588,7 +8681,7 @@ var CalculationsGenericMethods = class {
8588
8681
  lsDataForCalculation,
8589
8682
  lfDataForCalculation,
8590
8683
  lag,
8591
- LINK_TYPES2.SF
8684
+ LINK_TYPES3.SF
8592
8685
  );
8593
8686
  }
8594
8687
  getEarlyStartFromForwardPath(link) {
@@ -8611,10 +8704,10 @@ var CalculationsGenericMethods = class {
8611
8704
  this.activity
8612
8705
  );
8613
8706
  }
8614
- getLastWorkingHour(date2, activityCalendar, dir = "past") {
8707
+ getLastWorkingHour(date2, activityCalendar, dir = WORK_TIME_DIRECTION.PAST) {
8615
8708
  const normalizedDate = date2 instanceof Date ? date2 : new Date(date2);
8616
8709
  let resetedDate = moment_default(normalizedDate).clone();
8617
- if (this.isActivityInInitHour(activityCalendar, normalizedDate) && dir === "past") {
8710
+ if (this.isActivityInInitHour(activityCalendar, normalizedDate) && dir === WORK_TIME_DIRECTION.PAST) {
8618
8711
  resetedDate = resetedDate.hours(0).minutes(0).seconds(0).milliseconds(0);
8619
8712
  }
8620
8713
  let newDate = getNextWorkingHour({
@@ -8657,7 +8750,7 @@ var CalculationsGenericMethods = class {
8657
8750
  const lsSucessor2 = this.getLastWorkingHour(
8658
8751
  workTime,
8659
8752
  activityCalendar,
8660
- "past"
8753
+ WORK_TIME_DIRECTION.PAST
8661
8754
  );
8662
8755
  lfPred = addDurationToDate(
8663
8756
  activityCalendar,
@@ -8665,7 +8758,7 @@ var CalculationsGenericMethods = class {
8665
8758
  lfDataCalculation,
8666
8759
  this.activity
8667
8760
  );
8668
- lfPred = this.getLastWorkingHour(lfPred, activityCalendar, "past");
8761
+ lfPred = this.getLastWorkingHour(lfPred, activityCalendar, WORK_TIME_DIRECTION.PAST);
8669
8762
  lsPred = addDurationToDate(
8670
8763
  activityCalendar,
8671
8764
  lfPred,
@@ -8691,7 +8784,7 @@ var CalculationsGenericMethods = class {
8691
8784
  this.activity
8692
8785
  );
8693
8786
  if (!isMilestone) {
8694
- lfPred = this.getLastWorkingHour(lfPred, activityCalendar, "past", true);
8787
+ lfPred = this.getLastWorkingHour(lfPred, activityCalendar, WORK_TIME_DIRECTION.PAST, true);
8695
8788
  }
8696
8789
  return { ls: lsPred, lf: lfPred };
8697
8790
  }
@@ -8724,7 +8817,7 @@ var CalculationsGenericMethods = class {
8724
8817
  lfSucessor = this.getLastWorkingHour(
8725
8818
  lfSucessor,
8726
8819
  activityCalendar,
8727
- "past"
8820
+ WORK_TIME_DIRECTION.PAST
8728
8821
  );
8729
8822
  }
8730
8823
  lfPred = addDurationToDate(
@@ -8838,7 +8931,7 @@ var LinksConstraintCalculator2 = class extends CalculationsGenericMethods_defaul
8838
8931
  if (this.links.length === 0) {
8839
8932
  return new generic_calculations_default(
8840
8933
  this.gantt,
8841
- "backward"
8934
+ CALCULATION_DIRECTION.BACKWARD
8842
8935
  ).calculateStartAndFinishOfChainOrigin(this.activity);
8843
8936
  }
8844
8937
  let activityProgressMajorThanZeroButLessThanOneHundred = this.activity.progress > 0 && this.activity.progress < 100;
@@ -8950,7 +9043,7 @@ var LinksConstraintCalculator2 = class extends CalculationsGenericMethods_defaul
8950
9043
  if (!activityFromLink) {
8951
9044
  return;
8952
9045
  }
8953
- if (activityFromLink.progress > 0 && activityFromLink.type !== "project") {
9046
+ if (activityFromLink.progress > 0 && activityFromLink.type !== ACTIVITY_TYPE.PROJECT) {
8954
9047
  return;
8955
9048
  }
8956
9049
  const specialParamForFS = this.getSpecialCalculationParamForConstraintLink();
@@ -9083,7 +9176,7 @@ var restrictionCalculation_default2 = calculateRestriction3;
9083
9176
  // src/critical-path/legacy/backward-path/index.js
9084
9177
  var BackwardPath = class extends generic_calculations_default {
9085
9178
  constructor(ganttInstance, forwardPathCalculations, forwardConstraintsMap) {
9086
- super(ganttInstance, "backward");
9179
+ super(ganttInstance, CALCULATION_DIRECTION.BACKWARD);
9087
9180
  this.gantt = ganttInstance;
9088
9181
  this.chainStartActivities = /* @__PURE__ */ new Set();
9089
9182
  this.secondLevelActivities = /* @__PURE__ */ new Set();
@@ -9202,7 +9295,7 @@ var BackwardPath = class extends generic_calculations_default {
9202
9295
  activityReference
9203
9296
  );
9204
9297
  }
9205
- if (activityReference.type === "project") {
9298
+ if (activityReference.type === ACTIVITY_TYPE.PROJECT) {
9206
9299
  return this.doCalculationForParentType(activityReference);
9207
9300
  }
9208
9301
  if (progress === 100) {
@@ -9283,7 +9376,7 @@ var BackwardPath = class extends generic_calculations_default {
9283
9376
  if (!activityData) {
9284
9377
  continue;
9285
9378
  }
9286
- if (activityData.type === "project") {
9379
+ if (activityData.type === ACTIVITY_TYPE.PROJECT) {
9287
9380
  allLinkedHasProgress = false;
9288
9381
  }
9289
9382
  if (activityData.progress === 0) {
@@ -9302,7 +9395,7 @@ var BackwardPath = class extends generic_calculations_default {
9302
9395
  const parent = Number(activity.parent);
9303
9396
  let { ls, lf } = this.calculateStartAndFinishOfChainOrigin(
9304
9397
  activity,
9305
- "backward"
9398
+ CALCULATION_DIRECTION.BACKWARD
9306
9399
  );
9307
9400
  if (this.calculationsOfParentThatImpactChildrens.has(parent)) {
9308
9401
  ls = activity.start_date;
@@ -9371,9 +9464,9 @@ var BackwardPath = class extends generic_calculations_default {
9371
9464
  return links.map((link) => {
9372
9465
  let sourceId = this.gantt.getLink(link).source;
9373
9466
  let targetId = this.gantt.getLink(link).target;
9374
- if (!this.gantt.getTask(sourceId) || this.gantt.getTask(sourceId)?.type === "project")
9467
+ if (!this.gantt.getTask(sourceId) || this.gantt.getTask(sourceId)?.type === ACTIVITY_TYPE.PROJECT)
9375
9468
  return;
9376
- if (!this.gantt.getTask(targetId) || this.gantt.getTask(targetId)?.type === "project")
9469
+ if (!this.gantt.getTask(targetId) || this.gantt.getTask(targetId)?.type === ACTIVITY_TYPE.PROJECT)
9377
9470
  return;
9378
9471
  return link;
9379
9472
  }).filter(Boolean);
@@ -10075,7 +10168,7 @@ var CriticalPath = class {
10075
10168
  var legacy_default = CriticalPath;
10076
10169
 
10077
10170
  // src/critical-path/gantt-adapter.ts
10078
- var isFinishConstraint = (type) => type === "fnet" || type === "fnlt" || type === "mfo";
10171
+ var isFinishConstraint = (type) => type === CONSTRAINT_TYPE.FNET || type === CONSTRAINT_TYPE.FNLT || type === CONSTRAINT_TYPE.MFO;
10079
10172
  var startOfUtcDay3 = (date2) => new Date(
10080
10173
  Date.UTC(date2.getUTCFullYear(), date2.getUTCMonth(), date2.getUTCDate())
10081
10174
  );
@@ -10557,38 +10650,38 @@ var NON_SCHEDULING_INLINE_COLUMNS = /* @__PURE__ */ new Set([
10557
10650
  COLUMN.TAGS
10558
10651
  ]);
10559
10652
  var NON_SCHEDULING_KINDS = /* @__PURE__ */ new Set([
10560
- "activity-clipboard-clear",
10561
- "activity-copy",
10562
- "selection-toggle",
10563
- "selection-replace",
10564
- "visibility-set",
10565
- "filter-set",
10566
- "sort-set",
10567
- "sir-sync",
10568
- "activity-lookahead-sync",
10569
- "persistence-acknowledge",
10570
- "baseline-apply",
10571
- "ponderator-criterion-set",
10572
- "status-criteria-set"
10653
+ DISPATCH_ACTION_KIND.ACTIVITY_CLIPBOARD_CLEAR,
10654
+ DISPATCH_ACTION_KIND.ACTIVITY_COPY,
10655
+ DISPATCH_ACTION_KIND.SELECTION_TOGGLE,
10656
+ DISPATCH_ACTION_KIND.SELECTION_REPLACE,
10657
+ DISPATCH_ACTION_KIND.VISIBILITY_SET,
10658
+ DISPATCH_ACTION_KIND.FILTER_SET,
10659
+ DISPATCH_ACTION_KIND.SORT_SET,
10660
+ DISPATCH_ACTION_KIND.SIR_SYNC,
10661
+ DISPATCH_ACTION_KIND.ACTIVITY_LOOKAHEAD_SYNC,
10662
+ DISPATCH_ACTION_KIND.PERSISTENCE_ACKNOWLEDGE,
10663
+ DISPATCH_ACTION_KIND.BASELINE_APPLY,
10664
+ DISPATCH_ACTION_KIND.PONDERATOR_CRITERION_SET,
10665
+ DISPATCH_ACTION_KIND.STATUS_CRITERIA_SET
10573
10666
  ]);
10574
10667
  var PURE_VIEW_STATE_KINDS = /* @__PURE__ */ new Set([
10575
- "activity-clipboard-clear",
10576
- "activity-copy",
10577
- "selection-toggle",
10578
- "selection-replace",
10579
- "visibility-set",
10580
- "filter-set",
10581
- "sort-set"
10668
+ DISPATCH_ACTION_KIND.ACTIVITY_CLIPBOARD_CLEAR,
10669
+ DISPATCH_ACTION_KIND.ACTIVITY_COPY,
10670
+ DISPATCH_ACTION_KIND.SELECTION_TOGGLE,
10671
+ DISPATCH_ACTION_KIND.SELECTION_REPLACE,
10672
+ DISPATCH_ACTION_KIND.VISIBILITY_SET,
10673
+ DISPATCH_ACTION_KIND.FILTER_SET,
10674
+ DISPATCH_ACTION_KIND.SORT_SET
10582
10675
  ]);
10583
10676
  function reappliesViewState(action) {
10584
10677
  return !PURE_VIEW_STATE_KINDS.has(action.kind);
10585
10678
  }
10586
10679
  var NO_STRUCTURAL_EXEMPTIONS = /* @__PURE__ */ new Set();
10587
10680
  function editsOnlyNonSchedulingColumns(action) {
10588
- if (action.kind === "inline-edit") {
10681
+ if (action.kind === DISPATCH_ACTION_KIND.INLINE_EDIT) {
10589
10682
  return NON_SCHEDULING_INLINE_COLUMNS.has(action.column);
10590
10683
  }
10591
- if (action.kind === "bulk-edit") {
10684
+ if (action.kind === DISPATCH_ACTION_KIND.BULK_EDIT) {
10592
10685
  return action.edits.every(
10593
10686
  (edit) => NON_SCHEDULING_INLINE_COLUMNS.has(edit.column)
10594
10687
  );
@@ -10602,13 +10695,13 @@ function isSchedulingDispatch(action, structuralStaleKinds) {
10602
10695
  return true;
10603
10696
  }
10604
10697
  function dispatchChangesSchedulingState(action) {
10605
- if (action.kind === "activity-lookahead-sync") {
10698
+ if (action.kind === DISPATCH_ACTION_KIND.ACTIVITY_LOOKAHEAD_SYNC) {
10606
10699
  return action.persistedProgress !== void 0;
10607
10700
  }
10608
10701
  return isSchedulingDispatch(action, NO_STRUCTURAL_EXEMPTIONS);
10609
10702
  }
10610
10703
  function resolveRunCriticalPath(action) {
10611
- if (action.kind === "activity-lookahead-sync") {
10704
+ if (action.kind === DISPATCH_ACTION_KIND.ACTIVITY_LOOKAHEAD_SYNC) {
10612
10705
  return action.persistedProgress !== void 0;
10613
10706
  }
10614
10707
  return isSchedulingDispatch(
@@ -10623,9 +10716,11 @@ function resolveRunExpectedProgress(action) {
10623
10716
  );
10624
10717
  }
10625
10718
  function dispatchChangesProgress(action) {
10626
- if (action.kind === "activity-set-progress") return true;
10627
- if (action.kind === "inline-edit") return action.column === COLUMN.PROGRESS;
10628
- if (action.kind === "bulk-edit") {
10719
+ if (action.kind === DISPATCH_ACTION_KIND.ACTIVITY_SET_PROGRESS) return true;
10720
+ if (action.kind === DISPATCH_ACTION_KIND.INLINE_EDIT) {
10721
+ return action.column === COLUMN.PROGRESS;
10722
+ }
10723
+ if (action.kind === DISPATCH_ACTION_KIND.BULK_EDIT) {
10629
10724
  return action.edits.some((edit) => edit.column === COLUMN.PROGRESS);
10630
10725
  }
10631
10726
  return false;
@@ -10642,11 +10737,11 @@ var PROGRESS_AFFECTING_COLUMNS = /* @__PURE__ */ new Set([
10642
10737
  COLUMN.REAL_COST
10643
10738
  ]);
10644
10739
  function shouldRecomputeParentProgress(action) {
10645
- if (action.kind === "activity-set-progress") return true;
10646
- if (action.kind === "inline-edit") {
10740
+ if (action.kind === DISPATCH_ACTION_KIND.ACTIVITY_SET_PROGRESS) return true;
10741
+ if (action.kind === DISPATCH_ACTION_KIND.INLINE_EDIT) {
10647
10742
  return PROGRESS_AFFECTING_COLUMNS.has(action.column);
10648
10743
  }
10649
- if (action.kind === "bulk-edit") {
10744
+ if (action.kind === DISPATCH_ACTION_KIND.BULK_EDIT) {
10650
10745
  return action.edits.some(
10651
10746
  (edit) => PROGRESS_AFFECTING_COLUMNS.has(edit.column)
10652
10747
  );
@@ -10682,7 +10777,103 @@ function resolveDerivedPasses(action, autoSchedule, options) {
10682
10777
  return passes;
10683
10778
  }
10684
10779
 
10780
+ // src/internal/state/write-capture.ts
10781
+ var WRITE_OPERATION_KIND = {
10782
+ INSERT: "insert",
10783
+ REMOVE: "remove",
10784
+ LINK_ADD: "link-add",
10785
+ LINK_REMOVE: "link-remove",
10786
+ LINK_FIELD: "link-field"
10787
+ };
10788
+ var WriteCapture = class {
10789
+ _journal = null;
10790
+ begin() {
10791
+ this._journal = {
10792
+ dirty: /* @__PURE__ */ new Set(),
10793
+ before: /* @__PURE__ */ new Map(),
10794
+ ops: [],
10795
+ linkFieldCaptured: /* @__PURE__ */ new Set(),
10796
+ correlativeBefore: /* @__PURE__ */ new Map(),
10797
+ scheduledBefore: /* @__PURE__ */ new Map(),
10798
+ progressFallbackBefore: /* @__PURE__ */ new Map()
10799
+ };
10800
+ }
10801
+ peek() {
10802
+ return this._journal;
10803
+ }
10804
+ end() {
10805
+ this._journal = null;
10806
+ }
10807
+ note(key, current) {
10808
+ const journal = this._journal;
10809
+ if (!journal) return;
10810
+ if (!journal.before.has(key))
10811
+ journal.before.set(key, cloneCoreActivity(current));
10812
+ journal.dirty.add(key);
10813
+ }
10814
+ noteInsert(activityId) {
10815
+ this._journal?.ops.push({ kind: WRITE_OPERATION_KIND.INSERT, activityId });
10816
+ }
10817
+ noteRemove(activityId, current) {
10818
+ this._journal?.ops.push({
10819
+ kind: WRITE_OPERATION_KIND.REMOVE,
10820
+ activityId,
10821
+ before: cloneCoreActivity(current)
10822
+ });
10823
+ }
10824
+ noteLinkAdd(linkId) {
10825
+ this._journal?.ops.push({ kind: WRITE_OPERATION_KIND.LINK_ADD, linkId });
10826
+ }
10827
+ noteLinkRemove(linkId, current) {
10828
+ this._journal?.ops.push({
10829
+ kind: WRITE_OPERATION_KIND.LINK_REMOVE,
10830
+ linkId,
10831
+ before: cloneLink(current)
10832
+ });
10833
+ }
10834
+ noteCorrelativeBefore(activityId, before) {
10835
+ const journal = this._journal;
10836
+ if (!journal || journal.correlativeBefore.has(activityId)) return;
10837
+ const capturedBefore = journal.before.get(activityId)?.correlativeId;
10838
+ journal.correlativeBefore.set(
10839
+ activityId,
10840
+ typeof capturedBefore === "number" ? capturedBefore : before
10841
+ );
10842
+ }
10843
+ noteScheduledBefore(activityId, current) {
10844
+ const journal = this._journal;
10845
+ if (!journal) return;
10846
+ const beforeImage = cloneCoreActivity(current);
10847
+ if (!journal.scheduledBefore.has(activityId)) {
10848
+ journal.scheduledBefore.set(activityId, beforeImage);
10849
+ }
10850
+ if (!journal.before.has(activityId)) {
10851
+ journal.before.set(activityId, beforeImage);
10852
+ }
10853
+ journal.dirty.add(activityId);
10854
+ }
10855
+ noteLinkField(linkId, current) {
10856
+ const journal = this._journal;
10857
+ if (!journal || journal.linkFieldCaptured.has(linkId)) return;
10858
+ journal.linkFieldCaptured.add(linkId);
10859
+ journal.ops.push({
10860
+ kind: WRITE_OPERATION_KIND.LINK_FIELD,
10861
+ linkId,
10862
+ before: cloneLink(current)
10863
+ });
10864
+ }
10865
+ noteProgressFallback(activityId, current) {
10866
+ const journal = this._journal;
10867
+ if (!journal || journal.progressFallbackBefore.has(activityId)) return;
10868
+ journal.progressFallbackBefore.set(activityId, current);
10869
+ }
10870
+ };
10871
+ function cloneLink(link) {
10872
+ return { ...link };
10873
+ }
10874
+
10685
10875
  // src/dispatch/shared/post-mutation.ts
10876
+ var AUTOSCHEDULE_SCOPE = { ROOTS: "roots" };
10686
10877
  async function runPostMutation(deps, args) {
10687
10878
  const progressInvalidation = resolveProgressInvalidation(deps.adapter);
10688
10879
  const passes = resolvePasses(args, progressInvalidation);
@@ -10738,10 +10929,10 @@ function resolveProgressInvalidation(adapter) {
10738
10929
  }
10739
10930
  function collectStructuralProgressInvalidations(adapter, operations, affectParent) {
10740
10931
  for (const operation of operations) {
10741
- if (operation.kind === "insert") {
10932
+ if (operation.kind === WRITE_OPERATION_KIND.INSERT) {
10742
10933
  const inserted = adapter.getActivity(operation.activityId);
10743
10934
  if (inserted) affectParent(inserted.parentId);
10744
- } else if (operation.kind === "remove") {
10935
+ } else if (operation.kind === WRITE_OPERATION_KIND.REMOVE) {
10745
10936
  affectParent(operation.before.parentId);
10746
10937
  }
10747
10938
  }
@@ -10765,7 +10956,7 @@ function collectFieldProgressInvalidations(adapter, beforeById, dirtySeeds, affe
10765
10956
  }
10766
10957
  }
10767
10958
  async function runAutoschedule(deps, autoscheduleFrom, preventSummaryTargetPullback = false) {
10768
- const options = autoscheduleFrom === "roots" ? {} : { triggerId: autoscheduleFrom };
10959
+ const options = autoscheduleFrom === AUTOSCHEDULE_SCOPE.ROOTS ? {} : { triggerId: autoscheduleFrom };
10769
10960
  if (preventSummaryTargetPullback) {
10770
10961
  options.preventSummaryTargetPullback = true;
10771
10962
  }
@@ -10856,7 +11047,10 @@ var CONSTRAINT_EDIT_COLUMNS = /* @__PURE__ */ new Set([
10856
11047
  COLUMN.CONSTRAINT_TYPE,
10857
11048
  COLUMN.CONSTRAINT_DATE
10858
11049
  ]);
10859
- var MUST_CONSTRAINTS = /* @__PURE__ */ new Set(["mso", "mfo"]);
11050
+ var MUST_CONSTRAINTS = /* @__PURE__ */ new Set([
11051
+ CONSTRAINT_TYPE.MSO,
11052
+ CONSTRAINT_TYPE.MFO
11053
+ ]);
10860
11054
  function isConstraintEditColumn(column) {
10861
11055
  return CONSTRAINT_EDIT_COLUMNS.has(column);
10862
11056
  }
@@ -10987,6 +11181,10 @@ function snapshotToLink(l) {
10987
11181
  }
10988
11182
 
10989
11183
  // src/dispatch/shared/change-set.ts
11184
+ var SIR_DETECTION_PHASE = {
11185
+ BEFORE_DIFF: "before-diff",
11186
+ AFTER_DIFF: "after-diff"
11187
+ };
10990
11188
  async function assembleChangeSet(adapter, args) {
10991
11189
  const allTouched = collectChangeSetIds(adapter, args);
10992
11190
  const before = new Map(args.beforeSnap);
@@ -10996,7 +11194,7 @@ async function assembleChangeSet(adapter, args) {
10996
11194
  mergeDirtyBeforeImages(adapter, captured, insertedIds, before, allTouched);
10997
11195
  }
10998
11196
  const sirDetection = args.sirDetection;
10999
- const beforeDiffEffects = sirDetection === "before-diff" ? detectSirAutoReject(before, adapter, allTouched) : [];
11197
+ const beforeDiffEffects = sirDetection === SIR_DETECTION_PHASE.BEFORE_DIFF ? detectSirAutoReject(before, adapter, allTouched) : [];
11000
11198
  const correlativeBefore = buildCorrelativeBeforeMap(
11001
11199
  args.correlativeShifts,
11002
11200
  allTouched
@@ -11007,7 +11205,7 @@ async function assembleChangeSet(adapter, args) {
11007
11205
  allTouched,
11008
11206
  correlativeBefore
11009
11207
  );
11010
- const effects = sirDetection === "after-diff" ? detectSirAutoReject(before, adapter, allTouched) : beforeDiffEffects;
11208
+ const effects = sirDetection === SIR_DETECTION_PHASE.AFTER_DIFF ? detectSirAutoReject(before, adapter, allTouched) : beforeDiffEffects;
11011
11209
  const warnings = args.warnings ?? [];
11012
11210
  const linkChanges = mergeLinkChanges(
11013
11211
  args.links ?? [],
@@ -11026,7 +11224,7 @@ async function assembleChangeSet(adapter, args) {
11026
11224
  function buildCapturedCriticalPathLinkChanges(adapter, captured) {
11027
11225
  const changes = [];
11028
11226
  for (const operation of captured.ops) {
11029
- if (operation.kind !== "link-field") continue;
11227
+ if (operation.kind !== WRITE_OPERATION_KIND.LINK_FIELD) continue;
11030
11228
  const after = adapter.getLink(operation.linkId);
11031
11229
  if (!after) continue;
11032
11230
  const fields = {};
@@ -11041,7 +11239,7 @@ function buildCapturedCriticalPathLinkChanges(adapter, captured) {
11041
11239
  if (Object.keys(fields).length === 0) continue;
11042
11240
  changes.push({
11043
11241
  id: operation.linkId,
11044
- kind: "updated",
11242
+ kind: ENTITY_CHANGE_KIND.UPDATED,
11045
11243
  fields,
11046
11244
  after: snapshotToLink(after)
11047
11245
  });
@@ -11059,7 +11257,7 @@ function mergeLinkChanges(explicit, captured) {
11059
11257
  continue;
11060
11258
  }
11061
11259
  const current = merged[index];
11062
- if ((current.kind === "updated" || current.kind === "created") && change.kind === "updated") {
11260
+ if ((current.kind === ENTITY_CHANGE_KIND.UPDATED || current.kind === ENTITY_CHANGE_KIND.CREATED) && change.kind === ENTITY_CHANGE_KIND.UPDATED) {
11063
11261
  merged[index] = {
11064
11262
  ...current,
11065
11263
  fields: { ...current.fields, ...change.fields },
@@ -11077,8 +11275,8 @@ function mergeLinkChanges(explicit, captured) {
11077
11275
  continue;
11078
11276
  }
11079
11277
  const current = merged[index];
11080
- if (current.kind === "deleted") continue;
11081
- const capturedFields = current.kind === "created" ? Object.fromEntries(
11278
+ if (current.kind === ENTITY_CHANGE_KIND.DELETED) continue;
11279
+ const capturedFields = current.kind === ENTITY_CHANGE_KIND.CREATED ? Object.fromEntries(
11082
11280
  Object.entries(change.fields ?? {}).map(([field, value]) => [
11083
11281
  field,
11084
11282
  { before: void 0, after: value.after }
@@ -11123,7 +11321,7 @@ function mergeDirtyBeforeImages(adapter, captured, insertedIds, before, touched)
11123
11321
  }
11124
11322
  function collectInsertedIds(captured) {
11125
11323
  return new Set(
11126
- captured.ops.filter((operation) => operation.kind === "insert").map((operation) => operation.activityId)
11324
+ captured.ops.filter((operation) => operation.kind === WRITE_OPERATION_KIND.INSERT).map((operation) => operation.activityId)
11127
11325
  );
11128
11326
  }
11129
11327
 
@@ -11132,7 +11330,7 @@ function buildLinkChangesForBatch(applied, beforeLinks, adapter) {
11132
11330
  const out = [];
11133
11331
  for (const { op, finalLinkId, rejected } of applied) {
11134
11332
  if (rejected !== null) continue;
11135
- if (op.kind === "create") {
11333
+ if (op.kind === LINK_OPERATION_KIND.CREATE) {
11136
11334
  if (!finalLinkId) continue;
11137
11335
  const after = adapter.getLink(finalLinkId);
11138
11336
  if (!after) continue;
@@ -11163,7 +11361,7 @@ function buildLinkChangesForBatch(applied, beforeLinks, adapter) {
11163
11361
  if (Object.keys(fields2).length > 0) {
11164
11362
  out.push({
11165
11363
  id: String(finalLinkId),
11166
- kind: "updated",
11364
+ kind: ENTITY_CHANGE_KIND.UPDATED,
11167
11365
  fields: fields2,
11168
11366
  after: snapshotToLink(after)
11169
11367
  });
@@ -11172,7 +11370,7 @@ function buildLinkChangesForBatch(applied, beforeLinks, adapter) {
11172
11370
  }
11173
11371
  out.push({
11174
11372
  id: String(finalLinkId),
11175
- kind: "created",
11373
+ kind: ENTITY_CHANGE_KIND.CREATED,
11176
11374
  fields: {
11177
11375
  source: { before: void 0, after: String(after.source) },
11178
11376
  target: { before: void 0, after: String(after.target) },
@@ -11183,12 +11381,12 @@ function buildLinkChangesForBatch(applied, beforeLinks, adapter) {
11183
11381
  });
11184
11382
  continue;
11185
11383
  }
11186
- if (op.kind === "delete") {
11384
+ if (op.kind === LINK_OPERATION_KIND.DELETE) {
11187
11385
  if (adapter.getLink(op.linkId)) continue;
11188
11386
  const beforeLink2 = beforeLinks.get(op.linkId);
11189
11387
  out.push({
11190
11388
  id: String(op.linkId),
11191
- kind: "deleted",
11389
+ kind: ENTITY_CHANGE_KIND.DELETED,
11192
11390
  fields: beforeLink2 ? {
11193
11391
  source: { before: String(beforeLink2.source), after: void 0 },
11194
11392
  target: { before: String(beforeLink2.target), after: void 0 },
@@ -11214,7 +11412,7 @@ function buildLinkChangesForBatch(applied, beforeLinks, adapter) {
11214
11412
  }
11215
11413
  out.push({
11216
11414
  id: String(op.linkId),
11217
- kind: "updated",
11415
+ kind: ENTITY_CHANGE_KIND.UPDATED,
11218
11416
  fields,
11219
11417
  after: snapshotToLink(afterLink)
11220
11418
  });
@@ -11240,7 +11438,7 @@ function diffIncomingLinkLagChanges(beforeLags, adapter, activityId) {
11240
11438
  if (before === void 0 || before === Number(link.lag)) continue;
11241
11439
  out.push({
11242
11440
  id: String(link.id),
11243
- kind: "updated",
11441
+ kind: ENTITY_CHANGE_KIND.UPDATED,
11244
11442
  fields: {
11245
11443
  lag: {
11246
11444
  before,
@@ -11382,6 +11580,16 @@ async function dispatchInlineEdit(action, options, deps) {
11382
11580
  name: e.name,
11383
11581
  properties: e.properties ?? {}
11384
11582
  }));
11583
+ if (pipeline.trackEvent && !(action.column === COLUMN.PROGRESS && Number(parsed2.value) <= 0)) {
11584
+ trackingEvents.unshift({
11585
+ name: pipeline.trackEvent,
11586
+ properties: {
11587
+ activity_name: activitySnap.name,
11588
+ activity_id: activitySnap.id,
11589
+ activity_index: activitySnap.correlativeId
11590
+ }
11591
+ });
11592
+ }
11385
11593
  const constraintWarning = toConstraintWarning(
11386
11594
  action.activityId,
11387
11595
  changes.constraintWarning
@@ -11393,7 +11601,7 @@ async function dispatchInlineEdit(action, options, deps) {
11393
11601
  beforeSnap,
11394
11602
  touchedIds,
11395
11603
  scheduledIds,
11396
- sirDetection: "before-diff",
11604
+ sirDetection: SIR_DETECTION_PHASE.BEFORE_DIFF,
11397
11605
  links: linkChanges,
11398
11606
  trackingEvents,
11399
11607
  ...constraintWarning ? { warnings: [constraintWarning] } : {},
@@ -11403,9 +11611,8 @@ async function dispatchInlineEdit(action, options, deps) {
11403
11611
  }
11404
11612
 
11405
11613
  // src/dispatch/handlers/link.ts
11406
- var LINK_TYPE_VALUES = new Set(Object.values(LINK_TYPE));
11407
11614
  function isValidLinkType(value) {
11408
- return typeof value === "string" && LINK_TYPE_VALUES.has(value);
11615
+ return isLinkType(value);
11409
11616
  }
11410
11617
  function hasOwn(value, property) {
11411
11618
  return Object.hasOwn(value, property);
@@ -11618,7 +11825,7 @@ function pickAutoscheduleTrigger(applied, beforeLinks, adapter) {
11618
11825
  if (operation.rejected !== null) continue;
11619
11826
  const target = autoscheduleTarget(operation.op, beforeLinks, adapter);
11620
11827
  if (target !== null)
11621
- return adapter.hasChildren(target) ? "roots" : String(target);
11828
+ return adapter.hasChildren(target) ? AUTOSCHEDULE_SCOPE.ROOTS : String(target);
11622
11829
  }
11623
11830
  return null;
11624
11831
  }
@@ -11896,9 +12103,9 @@ function readNumber3(activity, key) {
11896
12103
  var NEW_ACTIVITY_DEFAULTS = Object.freeze({
11897
12104
  proplannerId: null,
11898
12105
  description: "",
11899
- type: "task",
12106
+ type: ACTIVITY_TYPE.TASK,
11900
12107
  progress: 0,
11901
- constraintType: "asap",
12108
+ constraintType: CONSTRAINT_TYPE.ASAP,
11902
12109
  constraintDate: null,
11903
12110
  autoScheduling: true,
11904
12111
  assignedDefaultCalendar: false,
@@ -12051,9 +12258,15 @@ function resolveStartDate(parent, fallback, override) {
12051
12258
  }
12052
12259
 
12053
12260
  // src/creation/parent-mutation-pipeline.ts
12261
+ var PARENT_MUTATION_SOURCE = {
12262
+ CREATE: "create",
12263
+ REPARENT: "reparent"
12264
+ };
12054
12265
  function snapshotOf(parent) {
12055
12266
  const type = parent.type;
12056
- if (type !== "task" && type !== "milestone") return null;
12267
+ if (type !== ACTIVITY_TYPE.TASK && type !== ACTIVITY_TYPE.MILESTONE) {
12268
+ return null;
12269
+ }
12057
12270
  const startDate = parent.startDate;
12058
12271
  const endDate = parent.endDate;
12059
12272
  if (!(startDate instanceof Date) || !(endDate instanceof Date)) return null;
@@ -12086,7 +12299,7 @@ function buildParentMutations(input) {
12086
12299
  }
12087
12300
  if (wasPromotableLeaf) {
12088
12301
  fields.type = PROMOTION_TARGET_TYPE;
12089
- if ((input.promotionSource ?? "create") === "create") {
12302
+ if ((input.promotionSource ?? PARENT_MUTATION_SOURCE.CREATE) === PARENT_MUTATION_SOURCE.CREATE) {
12090
12303
  fields.constraintType = CONSTRAINT_TYPE.ASAP;
12091
12304
  fields.constraintDate = null;
12092
12305
  }
@@ -12187,7 +12400,9 @@ function computeFractionalCidAtIndex(adapter, parentKey, targetIndex, excludeId)
12187
12400
 
12188
12401
  // src/dispatch/creation-overrides.ts
12189
12402
  var PUBLIC_CREATION_OVERRIDE_FIELDS = /* @__PURE__ */ new Set([
12190
- ...[...CREATION_OVERRIDE_FIELDS].filter((field) => field !== "durationHours"),
12403
+ ...[...CREATION_OVERRIDE_FIELDS].filter(
12404
+ (field) => field !== ACTIVITY_PROPERTY.DURATION_HOURS
12405
+ ),
12191
12406
  "durationDays"
12192
12407
  ]);
12193
12408
  function normalizeActivityCreationOverrides(raw, hoursPerDay) {
@@ -12209,7 +12424,7 @@ function normalizeActivityCreationOverrides(raw, hoursPerDay) {
12209
12424
  ok: true,
12210
12425
  value: {
12211
12426
  ...rest,
12212
- ...durationDays === 0 && (rest.type === void 0 || rest.type === "task") ? { type: "milestone" } : {},
12427
+ ...durationDays === 0 && (rest.type === void 0 || rest.type === ACTIVITY_TYPE.TASK) ? { type: ACTIVITY_TYPE.MILESTONE } : {},
12213
12428
  ...durationDays === void 0 ? {} : { durationHours: durationToHours(durationDays, hoursPerDay) }
12214
12429
  }
12215
12430
  };
@@ -12540,7 +12755,7 @@ function buildParentDemotionMutations(input) {
12540
12755
  durationHours: canonicalDuration,
12541
12756
  progress: 0,
12542
12757
  autoScheduling: true,
12543
- constraintType: "asap",
12758
+ constraintType: CONSTRAINT_TYPE.ASAP,
12544
12759
  constraintDate: null,
12545
12760
  hasNewActivities: false,
12546
12761
  ...canonicalEndDateField(
@@ -12692,7 +12907,7 @@ async function dispatchActivityDelete(action, options, deps) {
12692
12907
  },
12693
12908
  {
12694
12909
  action,
12695
- autoscheduleFrom: "roots",
12910
+ autoscheduleFrom: AUTOSCHEDULE_SCOPE.ROOTS,
12696
12911
  recomputeParentsFrom: parentsToCheck,
12697
12912
  now: deps.now,
12698
12913
  options
@@ -12720,7 +12935,7 @@ async function dispatchActivityDelete(action, options, deps) {
12720
12935
  beforeSnap,
12721
12936
  touchedIds,
12722
12937
  scheduledIds,
12723
- sirDetection: "after-diff",
12938
+ sirDetection: SIR_DETECTION_PHASE.AFTER_DIFF,
12724
12939
  links: buildLinkDeletions(beforeLinks),
12725
12940
  trackingEvents: [trackingEvent],
12726
12941
  hoursPerDay: sector.hoursPerDay,
@@ -12759,7 +12974,7 @@ function buildLinkDeletions(beforeLinks) {
12759
12974
  for (const [id, before] of beforeLinks.entries()) {
12760
12975
  out.push({
12761
12976
  id,
12762
- kind: "deleted",
12977
+ kind: ENTITY_CHANGE_KIND.DELETED,
12763
12978
  fields: {
12764
12979
  source: { before: String(before.source), after: void 0 },
12765
12980
  target: { before: String(before.target), after: void 0 },
@@ -12867,7 +13082,7 @@ async function dispatchActivityBatch(action, options, deps) {
12867
13082
  },
12868
13083
  {
12869
13084
  action,
12870
- autoscheduleFrom: action.items.length > 0 || action.links.length > 0 ? "roots" : null,
13085
+ autoscheduleFrom: action.items.length > 0 || action.links.length > 0 ? AUTOSCHEDULE_SCOPE.ROOTS : null,
12871
13086
  recomputeParentsFrom: createdIds,
12872
13087
  now: deps.now,
12873
13088
  options
@@ -12881,7 +13096,7 @@ async function dispatchActivityBatch(action, options, deps) {
12881
13096
  links: buildLinkChangesForBatch(appliedLinks, beforeLinks, deps.adapter),
12882
13097
  hoursPerDay: deps.sector.hoursPerDay,
12883
13098
  correlativeShifts: existingCorrelativeShifts,
12884
- ...action.mode === ACTIVITY_BATCH_MODE.REPLACE ? { sirDetection: "after-diff" } : {}
13099
+ ...action.mode === ACTIVITY_BATCH_MODE.REPLACE ? { sirDetection: SIR_DETECTION_PHASE.AFTER_DIFF } : {}
12885
13100
  });
12886
13101
  return {
12887
13102
  ok: true,
@@ -13240,7 +13455,7 @@ function dispatchSirSync(action, deps) {
13240
13455
  }
13241
13456
  const change = {
13242
13457
  id,
13243
- kind: "updated",
13458
+ kind: ENTITY_CHANGE_KIND.UPDATED,
13244
13459
  fields: { pendingRequestIds: { before, after } },
13245
13460
  after: structuredCloneActivity(updated)
13246
13461
  };
@@ -13416,7 +13631,7 @@ async function dispatchPersistenceAcknowledge(action, deps) {
13416
13631
  );
13417
13632
  activityChanges.push({
13418
13633
  id: assignment.id,
13419
- kind: "updated",
13634
+ kind: ENTITY_CHANGE_KIND.UPDATED,
13420
13635
  fields: {
13421
13636
  proplannerId: {
13422
13637
  before: previousProplannerId,
@@ -13433,7 +13648,7 @@ async function dispatchPersistenceAcknowledge(action, deps) {
13433
13648
  deps.adapter.setLinkProplannerId(assignment.id, assignment.proplannerId);
13434
13649
  linkChanges.push({
13435
13650
  id: assignment.id,
13436
- kind: "updated",
13651
+ kind: ENTITY_CHANGE_KIND.UPDATED,
13437
13652
  fields: {
13438
13653
  proplannerId: {
13439
13654
  before: previousProplannerId,
@@ -13496,7 +13711,7 @@ async function dispatchActivityLookaheadSync(action, options, deps) {
13496
13711
  if (Object.keys(fields).length === 0) continue;
13497
13712
  activities.push({
13498
13713
  id,
13499
- kind: "updated",
13714
+ kind: ENTITY_CHANGE_KIND.UPDATED,
13500
13715
  fields,
13501
13716
  after: {
13502
13717
  ...snapshot,
@@ -13554,6 +13769,285 @@ function hasInvalidPersistedProgress(action) {
13554
13769
  return progress !== void 0 && (action.activityIds.length !== 1 || !Number.isFinite(progress) || progress < 0 || progress > 100);
13555
13770
  }
13556
13771
 
13772
+ // src/dispatch/handlers/activity-lookahead-convert.ts
13773
+ function buildLookaheadConversionPlan(input, deps) {
13774
+ const { adapter } = deps;
13775
+ const requested = new Set(
13776
+ input.conversionRootIds.map((id) => String(id))
13777
+ );
13778
+ if (requested.size === 0) {
13779
+ throw new Error("Conversion requires at least one root");
13780
+ }
13781
+ for (const rootId of requested) validateRequestedRoot(rootId, adapter);
13782
+ const conversionRootIds = adapter.getVisualOrderIds().filter(
13783
+ (activityId) => requested.has(activityId) && !hasAncestorInSet(activityId, requested, adapter)
13784
+ );
13785
+ const branches = conversionRootIds.map(
13786
+ (rootId) => planConversionBranch(rootId, adapter)
13787
+ );
13788
+ const conversionGroups = branches.map(
13789
+ ({ conversionRootId, convertedActivities }) => ({
13790
+ conversionRootId,
13791
+ convertedActivities
13792
+ })
13793
+ );
13794
+ const milestoneMoves = branches.flatMap((branch) => branch.milestoneMoves);
13795
+ const activityIdsToDelete = branches.flatMap(
13796
+ (branch) => branch.activityIdsToDelete
13797
+ );
13798
+ const formerParents = branches.map((branch) => branch.formerParent);
13799
+ const idsToDelete = new Set(activityIdsToDelete);
13800
+ const linkIdsToDelete = collectIncidentLinkIds(idsToDelete, adapter);
13801
+ return {
13802
+ sourceStateRevision: deps.stateRevision,
13803
+ conversionRootIds,
13804
+ conversionGroups,
13805
+ milestoneMoves,
13806
+ activityIdsToDelete,
13807
+ linkIdsToDelete,
13808
+ formerParents
13809
+ };
13810
+ }
13811
+ async function dispatchActivityLookaheadConvert(action, options, deps) {
13812
+ if (action.expectedStateRevision !== deps.stateRevision) {
13813
+ return { ok: false, reason: REJECTION_REASON.STALE_STATE_REVISION };
13814
+ }
13815
+ const plan = buildLookaheadConversionPlan(action, deps);
13816
+ if (!conversionTopologyIsValid(plan, deps.adapter)) {
13817
+ return { ok: false, reason: REJECTION_REASON.HIERARCHY_CYCLE };
13818
+ }
13819
+ const { adapter, scheduler } = deps;
13820
+ scheduler.invalidateAllCaches();
13821
+ const context = await captureConversionMutationContext(plan, adapter);
13822
+ releaseDeletedCustomIds(plan, deps);
13823
+ applyConversionStructure(plan, adapter);
13824
+ applyFormerParentState(plan, context.deletedIds, adapter);
13825
+ const correlativeShifts = recomputeConversionRollups(plan, adapter);
13826
+ foldCorrelativeShifts(
13827
+ adapter,
13828
+ correlativeShifts,
13829
+ context.deletedIds,
13830
+ context.beforeSnap,
13831
+ context.touchedIds
13832
+ );
13833
+ const { scheduledIds } = await runPostMutation(
13834
+ {
13835
+ adapter,
13836
+ scheduler,
13837
+ sector: deps.sector,
13838
+ defaultBaseCalendarId: deps.defaultBaseCalendarId
13839
+ },
13840
+ {
13841
+ action,
13842
+ autoscheduleFrom: "roots",
13843
+ recomputeParentsFrom: context.touchedIds,
13844
+ now: deps.now,
13845
+ options,
13846
+ recomputeParentProgress: true
13847
+ }
13848
+ );
13849
+ const changes = await assembleChangeSet(adapter, {
13850
+ source: action,
13851
+ beforeSnap: context.beforeSnap,
13852
+ touchedIds: context.touchedIds,
13853
+ scheduledIds,
13854
+ sirDetection: "after-diff",
13855
+ links: buildLinkDeletions(context.beforeLinks),
13856
+ hoursPerDay: deps.sector.hoursPerDay,
13857
+ correlativeShifts
13858
+ });
13859
+ return buildConversionResult(plan, context, changes);
13860
+ }
13861
+ function planConversionBranch(rootId, adapter) {
13862
+ const root = requiredActivity(rootId, adapter);
13863
+ const branch = collectDescendantIds([rootId], adapter);
13864
+ branch.delete(rootId);
13865
+ if (branch.size === 0) {
13866
+ throw new Error(`Conversion root ${rootId} has no descendants`);
13867
+ }
13868
+ const descendants = adapter.getVisualOrderIds().filter((activityId) => branch.has(activityId)).map((activityId) => requiredActivity(activityId, adapter));
13869
+ validateFiniteActivity(root);
13870
+ for (const descendant of descendants) validateFiniteActivity(descendant);
13871
+ const convertible = descendants.filter(
13872
+ (activity) => activity.type !== ACTIVITY_TYPE.MILESTONE
13873
+ );
13874
+ const milestones = descendants.filter(
13875
+ (activity) => activity.type === ACTIVITY_TYPE.MILESTONE
13876
+ );
13877
+ const persistedIds = collectPersistedIds(root, convertible);
13878
+ return {
13879
+ conversionRootId: rootId,
13880
+ convertedActivities: convertible.map(
13881
+ (activity) => buildConvertedSnapshot(activity, persistedIds)
13882
+ ),
13883
+ milestoneMoves: buildMilestoneMoves(root, milestones),
13884
+ activityIdsToDelete: convertible.map((activity) => activity.id),
13885
+ formerParent: {
13886
+ activity: structuredCloneActivity(root),
13887
+ hasConvertedActivities: convertible.length > 0
13888
+ }
13889
+ };
13890
+ }
13891
+ function collectPersistedIds(root, converted) {
13892
+ const persistedIds = /* @__PURE__ */ new Map();
13893
+ if (converted.length > 0) persistedIds.set(root.id, persistedIdOf(root));
13894
+ for (const activity of converted) {
13895
+ persistedIds.set(activity.id, persistedIdOf(activity));
13896
+ }
13897
+ return persistedIds;
13898
+ }
13899
+ function buildConvertedSnapshot(activity, persistedIds) {
13900
+ const snapshot = structuredCloneActivity(activity);
13901
+ const parentKey = normalizeParentKey(activity.parentId);
13902
+ const persistedParentId = persistedIds.get(parentKey);
13903
+ snapshot.parentId = persistedParentId === void 0 ? null : String(persistedParentId);
13904
+ return snapshot;
13905
+ }
13906
+ function buildMilestoneMoves(root, milestones) {
13907
+ const moves = [];
13908
+ const parentId = normalizeParentKey(root.parentId);
13909
+ let afterSiblingId = root.id;
13910
+ for (const milestone of milestones) {
13911
+ moves.push({ activityId: milestone.id, parentId, afterSiblingId });
13912
+ afterSiblingId = milestone.id;
13913
+ }
13914
+ return moves;
13915
+ }
13916
+ async function captureConversionMutationContext(plan, adapter) {
13917
+ const deletedIds = new Set(plan.activityIdsToDelete);
13918
+ const touchedIds = /* @__PURE__ */ new Set([
13919
+ ...plan.conversionRootIds,
13920
+ ...plan.activityIdsToDelete,
13921
+ ...plan.milestoneMoves.map(({ activityId }) => activityId),
13922
+ ...plan.milestoneMoves.map(({ parentId }) => parentId).filter((parentId) => parentId !== ROOT_PARENT_ID)
13923
+ ]);
13924
+ return {
13925
+ deletedIds,
13926
+ touchedIds,
13927
+ beforeSnap: await snapshotActivities(adapter, touchedIds),
13928
+ beforeLinks: snapshotLinks(plan.linkIdsToDelete, adapter),
13929
+ viewStateChanges: captureDeletedViewState(adapter, deletedIds)
13930
+ };
13931
+ }
13932
+ function releaseDeletedCustomIds(plan, deps) {
13933
+ for (const activityId of plan.activityIdsToDelete) {
13934
+ const customId = deps.adapter.getActivity(activityId)?.customId;
13935
+ if (customId) deps.customIdTracker.releaseCustomId(customId);
13936
+ }
13937
+ }
13938
+ function applyConversionStructure(plan, adapter) {
13939
+ for (const move of plan.milestoneMoves) {
13940
+ adapter.setActivityFields(move.activityId, {
13941
+ parentId: move.parentId,
13942
+ correlativeId: computeInsertionCorrelativeId(
13943
+ adapter,
13944
+ move.parentId,
13945
+ move.afterSiblingId,
13946
+ void 0
13947
+ )
13948
+ });
13949
+ }
13950
+ for (const linkId of plan.linkIdsToDelete) adapter.removeLink(linkId);
13951
+ for (const activityId of [...plan.activityIdsToDelete].reverse()) {
13952
+ adapter.removeActivity(activityId);
13953
+ }
13954
+ for (const { activity } of plan.formerParents) {
13955
+ adapter.setActivityField(
13956
+ activity.id,
13957
+ ACTIVITY_PROPERTY.TYPE,
13958
+ ACTIVITY_TYPE.TASK
13959
+ );
13960
+ }
13961
+ }
13962
+ function applyFormerParentState(plan, deletedIds, adapter) {
13963
+ for (const { activity, hasConvertedActivities } of plan.formerParents) {
13964
+ const live = requiredActivity(activity.id, adapter);
13965
+ const cleanup = buildParentNewActivitiesCleanup({
13966
+ parent: live,
13967
+ idsRemoved: deletedIds
13968
+ });
13969
+ adapter.setActivityFields(activity.id, {
13970
+ isLookahead: activity.isLookahead || hasConvertedActivities,
13971
+ hasLookaheadTasks: activity.hasLookaheadTasks || hasConvertedActivities,
13972
+ ...cleanup?.fields ?? {}
13973
+ });
13974
+ }
13975
+ }
13976
+ function recomputeConversionRollups(plan, adapter) {
13977
+ for (const { activity } of plan.formerParents) {
13978
+ recomputeRollupCascadesForParent(activity.parentId, adapter);
13979
+ }
13980
+ return recomputeCorrelativeIds(adapter);
13981
+ }
13982
+ function buildConversionResult(plan, context, changes) {
13983
+ const deletedSnapshots = /* @__PURE__ */ new Map();
13984
+ for (const activityId of context.deletedIds) {
13985
+ const snapshot = context.beforeSnap.get(activityId);
13986
+ if (snapshot) deletedSnapshots.set(activityId, snapshot);
13987
+ }
13988
+ return {
13989
+ ok: true,
13990
+ changes: context.viewStateChanges.length === 0 ? changes : { ...changes, viewState: context.viewStateChanges },
13991
+ conversionGroups: plan.conversionGroups.map(
13992
+ ({ conversionRootId, convertedActivities }) => ({
13993
+ conversionRootId,
13994
+ convertedActivities: convertedActivities.map(
13995
+ (activity) => structuredCloneActivity(activity)
13996
+ )
13997
+ })
13998
+ ),
13999
+ __beforeSnap: deletedSnapshots,
14000
+ __beforeLinks: context.beforeLinks
14001
+ };
14002
+ }
14003
+ function validateRequestedRoot(rootId, adapter) {
14004
+ const activity = adapter.getActivity(rootId);
14005
+ if (!activity) throw new Error(`Conversion root ${rootId} was not found`);
14006
+ if (activity.type === ACTIVITY_TYPE.PROJECT && activity.correlativeId === ROOT_PROJECT_CORRELATIVE_ID) {
14007
+ throw new Error(`Conversion root ${rootId} is the visual project root`);
14008
+ }
14009
+ }
14010
+ function requiredActivity(activityId, adapter) {
14011
+ const activity = adapter.getActivity(activityId);
14012
+ if (!activity)
14013
+ throw new Error(`Conversion activity ${activityId} is missing`);
14014
+ return activity;
14015
+ }
14016
+ function persistedIdOf(activity) {
14017
+ if (activity.proplannerId == null) {
14018
+ throw new Error(
14019
+ `Conversion activity ${activity.id} has no persisted identifier`
14020
+ );
14021
+ }
14022
+ return activity.proplannerId;
14023
+ }
14024
+ function validateFiniteActivity(activity) {
14025
+ if (!Number.isFinite(activity.startDate.getTime())) {
14026
+ throw new Error(`Conversion activity ${activity.id} has invalid startDate`);
14027
+ }
14028
+ if (!Number.isFinite(activity.endDate.getTime())) {
14029
+ throw new Error(`Conversion activity ${activity.id} has invalid endDate`);
14030
+ }
14031
+ }
14032
+ function conversionTopologyIsValid(plan, adapter) {
14033
+ const proposedPort = adapter.fork();
14034
+ applyConversionStructure(plan, proposedPort);
14035
+ return validateTopologyCommit({
14036
+ port: adapter,
14037
+ proposedPort,
14038
+ currentLinks: adapter.getAllLinks(),
14039
+ proposedLinks: proposedPort.getAllLinks()
14040
+ }).ok;
14041
+ }
14042
+ function snapshotLinks(linkIds, adapter) {
14043
+ const snapshots = /* @__PURE__ */ new Map();
14044
+ for (const linkId of linkIds) {
14045
+ const link = adapter.getLink(linkId);
14046
+ if (link) snapshots.set(linkId, { ...link });
14047
+ }
14048
+ return snapshots;
14049
+ }
14050
+
13557
14051
  // src/internal/hierarchy/invalid-links.ts
13558
14052
  function collectInvalidLinkIdsForCycle(movedActivityIds, adapter) {
13559
14053
  const moved = /* @__PURE__ */ new Set();
@@ -13706,7 +14200,7 @@ async function dispatchActivityMove(action, options, deps) {
13706
14200
  newChildId: action.activityId,
13707
14201
  getParent: (id) => adapter.getActivity(id) ?? null,
13708
14202
  isCurrentlyLeaf: wasLeaf,
13709
- promotionSource: "reparent"
14203
+ promotionSource: PARENT_MUTATION_SOURCE.REPARENT
13710
14204
  });
13711
14205
  if (promotion) {
13712
14206
  for (const [key, value] of Object.entries(promotion.fields)) {
@@ -13819,7 +14313,7 @@ async function dispatchActivityMove(action, options, deps) {
13819
14313
  beforeSnap,
13820
14314
  touchedIds: touched,
13821
14315
  scheduledIds,
13822
- sirDetection: "before-diff",
14316
+ sirDetection: SIR_DETECTION_PHASE.BEFORE_DIFF,
13823
14317
  trackingEvents: [trackingEvent],
13824
14318
  hoursPerDay: sector.hoursPerDay
13825
14319
  })
@@ -13927,7 +14421,7 @@ async function dispatchActivityIndent(action, options, deps) {
13927
14421
  newChildId: activityId,
13928
14422
  getParent: (id) => adapter.getActivity(id) ?? null,
13929
14423
  isCurrentlyLeaf: wasLeaf,
13930
- promotionSource: "reparent"
14424
+ promotionSource: PARENT_MUTATION_SOURCE.REPARENT
13931
14425
  });
13932
14426
  if (promotion) {
13933
14427
  for (const [key, value] of Object.entries(promotion.fields)) {
@@ -13955,7 +14449,7 @@ async function dispatchActivityIndent(action, options, deps) {
13955
14449
  adapter.setActivityField(
13956
14450
  newParentId,
13957
14451
  ACTIVITY_PROPERTY.CONSTRAINT_TYPE,
13958
- "asap"
14452
+ CONSTRAINT_TYPE.ASAP
13959
14453
  );
13960
14454
  adapter.setActivityField(
13961
14455
  newParentId,
@@ -14231,7 +14725,7 @@ async function dispatchActivityOutdent(action, options, deps) {
14231
14725
  },
14232
14726
  {
14233
14727
  action,
14234
- autoscheduleFrom: succeededIds.length > 0 ? "roots" : null,
14728
+ autoscheduleFrom: succeededIds.length > 0 ? AUTOSCHEDULE_SCOPE.ROOTS : null,
14235
14729
  recomputeParentsFrom: succeededIds,
14236
14730
  now: deps.now,
14237
14731
  options
@@ -14294,7 +14788,7 @@ async function dispatchActivitySetProgress(action, options, deps) {
14294
14788
  }
14295
14789
  const editGate = pipeline.canEdit(activitySnap, ctx.hierarchy);
14296
14790
  if (!editGate.allowed) {
14297
- const declaredButtonOverride = action.origin === "action-button" && (editGate.reason === "has_lookahead_tasks" || editGate.reason === "summary");
14791
+ const declaredButtonOverride = action.origin === ACTIVITY_PROGRESS_ORIGIN.ACTION_BUTTON && (editGate.reason === EDIT_DENIAL_REASON.HAS_LOOKAHEAD_TASKS || editGate.reason === EDIT_DENIAL_REASON.SUMMARY);
14298
14792
  if (!declaredButtonOverride) {
14299
14793
  return {
14300
14794
  ok: false,
@@ -14415,7 +14909,7 @@ async function dispatchDatesBatch(action, options, deps) {
14415
14909
  },
14416
14910
  {
14417
14911
  action,
14418
- autoscheduleFrom: needsAutoSchedule ? "roots" : null,
14912
+ autoscheduleFrom: needsAutoSchedule ? AUTOSCHEDULE_SCOPE.ROOTS : null,
14419
14913
  recomputeParentsFrom: touchedIds,
14420
14914
  now: deps.now,
14421
14915
  options
@@ -14429,7 +14923,7 @@ async function dispatchDatesBatch(action, options, deps) {
14429
14923
  beforeSnap,
14430
14924
  touchedIds,
14431
14925
  scheduledIds,
14432
- sirDetection: "before-diff",
14926
+ sirDetection: SIR_DETECTION_PHASE.BEFORE_DIFF,
14433
14927
  links: linkChanges,
14434
14928
  trackingEvents,
14435
14929
  warnings,
@@ -14576,7 +15070,7 @@ async function dispatchBulkEdit(action, options, deps) {
14576
15070
  }
14577
15071
  const postMutationArgs = {
14578
15072
  action,
14579
- autoscheduleFrom: needsAutoSchedule ? "roots" : null,
15073
+ autoscheduleFrom: needsAutoSchedule ? AUTOSCHEDULE_SCOPE.ROOTS : null,
14580
15074
  recomputeParentsFrom: touchedIds,
14581
15075
  now: deps.now,
14582
15076
  options
@@ -14621,7 +15115,7 @@ async function dispatchBulkEdit(action, options, deps) {
14621
15115
  beforeSnap,
14622
15116
  touchedIds,
14623
15117
  scheduledIds,
14624
- sirDetection: "before-diff",
15118
+ sirDetection: SIR_DETECTION_PHASE.BEFORE_DIFF,
14625
15119
  links: linkChanges,
14626
15120
  trackingEvents,
14627
15121
  warnings,
@@ -14758,6 +15252,51 @@ function mergeBeforeSnapshots2(beforeSnap, ids, deps) {
14758
15252
  }
14759
15253
  }
14760
15254
 
15255
+ // src/shared/load-diagnostics.ts
15256
+ var LOAD_DIAGNOSTIC_SAMPLE_LIMIT = 10;
15257
+ var LOAD_DIAGNOSTIC_CODE = {
15258
+ INVALID_BASELINE_POINT: "invalid_baseline_point",
15259
+ UNKNOWN_CONSTRAINT: "unknown_constraint",
15260
+ ORPHAN_ACTIVITY: "orphan_activity",
15261
+ INVALID_LINK: "invalid_link",
15262
+ DUPLICATE_LINK: "duplicate_link"
15263
+ };
15264
+ var LOAD_DIAGNOSTIC_CODE_ORDER = [
15265
+ LOAD_DIAGNOSTIC_CODE.INVALID_BASELINE_POINT,
15266
+ LOAD_DIAGNOSTIC_CODE.UNKNOWN_CONSTRAINT,
15267
+ LOAD_DIAGNOSTIC_CODE.ORPHAN_ACTIVITY,
15268
+ LOAD_DIAGNOSTIC_CODE.INVALID_LINK,
15269
+ LOAD_DIAGNOSTIC_CODE.DUPLICATE_LINK
15270
+ ];
15271
+ var noopLoadDiagnosticRecorder = () => {
15272
+ };
15273
+ function createLoadDiagnosticsCollector() {
15274
+ const counts = /* @__PURE__ */ new Map();
15275
+ const samples = /* @__PURE__ */ new Map();
15276
+ const record = (code, sampleId) => {
15277
+ counts.set(code, (counts.get(code) ?? 0) + 1);
15278
+ const codeSamples = samples.get(code) ?? [];
15279
+ if (codeSamples.length < LOAD_DIAGNOSTIC_SAMPLE_LIMIT && !codeSamples.includes(sampleId)) {
15280
+ codeSamples.push(sampleId);
15281
+ samples.set(code, codeSamples);
15282
+ }
15283
+ };
15284
+ const snapshot = () => Object.freeze(
15285
+ LOAD_DIAGNOSTIC_CODE_ORDER.flatMap((code) => {
15286
+ const count = counts.get(code);
15287
+ if (count === void 0) return [];
15288
+ return [
15289
+ Object.freeze({
15290
+ code,
15291
+ count,
15292
+ sampleIds: Object.freeze([...samples.get(code) ?? []])
15293
+ })
15294
+ ];
15295
+ })
15296
+ );
15297
+ return { record, snapshot };
15298
+ }
15299
+
14761
15300
  // src/baselines/normalize-baseline-point.ts
14762
15301
  function parseBaselineDate(value) {
14763
15302
  return typeof value === "string" && value.length > 0 ? parseBackendDate(value) : value instanceof Date ? value : null;
@@ -14767,11 +15306,17 @@ function parseFiniteNonNegative(value) {
14767
15306
  if (!Number.isFinite(numeric) || numeric < 0) return null;
14768
15307
  return numeric;
14769
15308
  }
14770
- function normalizeBaselinePoint(point, reporter) {
15309
+ function normalizeBaselinePoint(point, reporter, diagnostic) {
14771
15310
  const durationDays = parseFiniteNonNegative(point.duration);
14772
15311
  const cost = parseFiniteNonNegative(point.cost);
14773
15312
  const workHours = parseFiniteNonNegative(point.hh_work);
14774
15313
  if (durationDays === null || cost === null || workHours === null) {
15314
+ if (diagnostic) {
15315
+ diagnostic.record(
15316
+ LOAD_DIAGNOSTIC_CODE.INVALID_BASELINE_POINT,
15317
+ diagnostic.sampleId
15318
+ );
15319
+ }
14775
15320
  reporter.warn(
14776
15321
  `[baseline] dropping point with non-finite/negative magnitude \u2014 duration=${JSON.stringify(point.duration)}, cost=${JSON.stringify(point.cost)}, hh_work=${JSON.stringify(point.hh_work)}`
14777
15322
  );
@@ -14793,7 +15338,7 @@ function normalizeBaselinePoint(point, reporter) {
14793
15338
  }
14794
15339
 
14795
15340
  // src/baselines/apply-baseline-points.ts
14796
- function applyBaselinePoints(adapter, points, reporter) {
15341
+ function applyBaselinePoints(adapter, points, reporter, recordDiagnostic = noopLoadDiagnosticRecorder) {
14797
15342
  const idByProplanner = /* @__PURE__ */ new Map();
14798
15343
  adapter.forEachActivity((a, id) => {
14799
15344
  const pid = a.proplannerId;
@@ -14802,9 +15347,21 @@ function applyBaselinePoints(adapter, points, reporter) {
14802
15347
  const grouped = /* @__PURE__ */ new Map();
14803
15348
  for (const p of points) {
14804
15349
  const activityId = p.activityId;
14805
- if (typeof activityId !== "number") continue;
15350
+ if (typeof activityId !== "number") {
15351
+ recordDiagnostic(
15352
+ LOAD_DIAGNOSTIC_CODE.INVALID_BASELINE_POINT,
15353
+ String(activityId ?? "unknown")
15354
+ );
15355
+ continue;
15356
+ }
14806
15357
  const coreId = idByProplanner.get(activityId);
14807
- if (coreId === void 0) continue;
15358
+ if (coreId === void 0) {
15359
+ recordDiagnostic(
15360
+ LOAD_DIAGNOSTIC_CODE.INVALID_BASELINE_POINT,
15361
+ String(activityId)
15362
+ );
15363
+ continue;
15364
+ }
14808
15365
  const arr = grouped.get(coreId);
14809
15366
  if (arr) arr.push(p);
14810
15367
  else grouped.set(coreId, [p]);
@@ -14814,7 +15371,12 @@ function applyBaselinePoints(adapter, points, reporter) {
14814
15371
  adapter.setActivityField(
14815
15372
  coreId,
14816
15373
  "baselinePoints",
14817
- group.map((point) => normalizeBaselinePoint(point, reporter)).filter((point) => point !== null)
15374
+ group.map(
15375
+ (point) => normalizeBaselinePoint(point, reporter, {
15376
+ record: recordDiagnostic,
15377
+ sampleId: coreId
15378
+ })
15379
+ ).filter((point) => point !== null)
14818
15380
  );
14819
15381
  changed.push(coreId);
14820
15382
  }
@@ -14859,12 +15421,13 @@ function emitBaselineSnapshotColumns(state) {
14859
15421
  }
14860
15422
 
14861
15423
  // src/baselines/apply-baseline-overlay.ts
14862
- function applyBaselineOverlay(state, points, now, reporter, defaultBaseCalendarId = null) {
15424
+ function applyBaselineOverlay(state, points, now, reporter, defaultBaseCalendarId = null, recordDiagnostic = noopLoadDiagnosticRecorder) {
14863
15425
  const changed = /* @__PURE__ */ new Set();
14864
15426
  for (const id of applyBaselinePoints(
14865
15427
  state,
14866
15428
  points,
14867
- reporter
15429
+ reporter,
15430
+ recordDiagnostic
14868
15431
  )) {
14869
15432
  changed.add(id);
14870
15433
  }
@@ -15103,7 +15666,7 @@ async function dispatchCalendarReconcile(action, options, deps) {
15103
15666
  },
15104
15667
  {
15105
15668
  action,
15106
- autoscheduleFrom: "roots",
15669
+ autoscheduleFrom: AUTOSCHEDULE_SCOPE.ROOTS,
15107
15670
  recomputeParentsFrom: touchedIds,
15108
15671
  now: deps.now,
15109
15672
  options
@@ -15174,7 +15737,7 @@ function dispatchActivityCopy(action, deps) {
15174
15737
  throw new Error(`Selected activity ${id} is missing`);
15175
15738
  return {
15176
15739
  originalId: id,
15177
- originalParentId: activity.parentId ?? "0",
15740
+ originalParentId: activity.parentId ?? ROOT_PARENT_ID,
15178
15741
  overrides: copyOverrides(activity)
15179
15742
  };
15180
15743
  }),
@@ -15183,7 +15746,7 @@ function dispatchActivityCopy(action, deps) {
15183
15746
  ).map((link) => cloneDomainValue(link))
15184
15747
  };
15185
15748
  const selection = dispatchSelectionReplace(
15186
- { kind: "selection-replace", activityIds: [] },
15749
+ { kind: DISPATCH_ACTION_KIND.SELECTION_REPLACE, activityIds: [] },
15187
15750
  { adapter: deps.adapter }
15188
15751
  );
15189
15752
  if (!selection.ok) return selection;
@@ -15245,6 +15808,7 @@ async function dispatchActivityPasteCopied(action, options, deps) {
15245
15808
  const afterSiblingId = mappedParent === void 0 ? previousRootId ?? destination.afterSiblingId : void 0;
15246
15809
  const created = await createActivityCore(
15247
15810
  {
15811
+ kind: DISPATCH_ACTION_KIND.ACTIVITY_CREATE,
15248
15812
  parentId: mappedParent ?? destination.parentId,
15249
15813
  ...afterSiblingId === void 0 ? {} : { afterSiblingId },
15250
15814
  overrides: cloneDomainValue(copied.overrides),
@@ -15278,7 +15842,7 @@ async function dispatchActivityPasteCopied(action, options, deps) {
15278
15842
  const target = originalToNew.get(copiedLink.target);
15279
15843
  if (source === void 0 || target === void 0) return invariantFailure();
15280
15844
  const operation = {
15281
- kind: "create",
15845
+ kind: LINK_OPERATION_KIND.CREATE,
15282
15846
  source,
15283
15847
  target,
15284
15848
  type: copiedLink.type,
@@ -15330,94 +15894,97 @@ async function dispatchActivityPasteCopied(action, options, deps) {
15330
15894
 
15331
15895
  // src/dispatch/dispatch.ts
15332
15896
  async function performDispatch(action, options, deps) {
15333
- if (action.kind === "activity-copy") {
15897
+ if (action.kind === DISPATCH_ACTION_KIND.ACTIVITY_COPY) {
15334
15898
  return dispatchActivityCopy(action, {
15335
15899
  adapter: deps.adapter,
15336
15900
  clipboard: deps.activityClipboard
15337
15901
  });
15338
15902
  }
15339
- if (action.kind === "calendar-reconcile") {
15903
+ if (action.kind === DISPATCH_ACTION_KIND.CALENDAR_RECONCILE) {
15340
15904
  return dispatchCalendarReconcile(action, options, deps);
15341
15905
  }
15342
- if (action.kind === "activity-clipboard-clear") {
15906
+ if (action.kind === DISPATCH_ACTION_KIND.ACTIVITY_CLIPBOARD_CLEAR) {
15343
15907
  return dispatchActivityClipboardClear(action, deps.activityClipboard);
15344
15908
  }
15345
- if (action.kind === "activity-paste-copied") {
15909
+ if (action.kind === DISPATCH_ACTION_KIND.ACTIVITY_PASTE_COPIED) {
15346
15910
  return dispatchActivityPasteCopied(action, options, deps);
15347
15911
  }
15348
- if (action.kind === "activity-batch") {
15912
+ if (action.kind === ACTIVITY_BATCH_ACTION_KIND) {
15349
15913
  return dispatchActivityBatch(action, options, deps);
15350
15914
  }
15351
- if (action.kind === "persistence-acknowledge") {
15915
+ if (action.kind === DISPATCH_ACTION_KIND.PERSISTENCE_ACKNOWLEDGE) {
15352
15916
  return dispatchPersistenceAcknowledge(action, deps);
15353
15917
  }
15354
- if (action.kind === "baseline-apply") {
15918
+ if (action.kind === DISPATCH_ACTION_KIND.BASELINE_APPLY) {
15355
15919
  return dispatchBaselineApply(action, deps);
15356
15920
  }
15357
- if (action.kind === "ponderator-criterion-set") {
15921
+ if (action.kind === DISPATCH_ACTION_KIND.PONDERATOR_CRITERION_SET) {
15358
15922
  return dispatchPonderatorCriterionSet(action, deps);
15359
15923
  }
15360
- if (action.kind === "status-criteria-set") {
15924
+ if (action.kind === DISPATCH_ACTION_KIND.STATUS_CRITERIA_SET) {
15361
15925
  return dispatchStatusCriteriaSet(action, deps);
15362
15926
  }
15363
- if (action.kind === "link-create" || action.kind === "link-update" || action.kind === "link-delete") {
15927
+ if (action.kind === DISPATCH_ACTION_KIND.LINK_CREATE || action.kind === DISPATCH_ACTION_KIND.LINK_UPDATE || action.kind === DISPATCH_ACTION_KIND.LINK_DELETE) {
15364
15928
  return dispatchLink(action, options, deps);
15365
15929
  }
15366
- if (action.kind === "links-batch") {
15930
+ if (action.kind === DISPATCH_ACTION_KIND.LINKS_BATCH) {
15367
15931
  return dispatchLinksBatch(action, options, deps);
15368
15932
  }
15369
- if (action.kind === "activity-create") {
15933
+ if (action.kind === DISPATCH_ACTION_KIND.ACTIVITY_CREATE) {
15370
15934
  return dispatchActivityCreate(action, options, deps);
15371
15935
  }
15372
- if (action.kind === "activity-delete") {
15936
+ if (action.kind === DISPATCH_ACTION_KIND.ACTIVITY_DELETE) {
15373
15937
  return dispatchActivityDelete(action, options, deps);
15374
15938
  }
15375
- if (action.kind === "activity-move") {
15939
+ if (action.kind === DISPATCH_ACTION_KIND.ACTIVITY_MOVE) {
15376
15940
  return dispatchActivityMove(action, options, deps);
15377
15941
  }
15378
- if (action.kind === "activity-indent") {
15942
+ if (action.kind === DISPATCH_ACTION_KIND.ACTIVITY_INDENT) {
15379
15943
  return dispatchActivityIndent(action, options, deps);
15380
15944
  }
15381
- if (action.kind === "activity-outdent") {
15945
+ if (action.kind === DISPATCH_ACTION_KIND.ACTIVITY_OUTDENT) {
15382
15946
  return dispatchActivityOutdent(action, options, deps);
15383
15947
  }
15384
- if (action.kind === "activity-set-progress") {
15948
+ if (action.kind === DISPATCH_ACTION_KIND.ACTIVITY_SET_PROGRESS) {
15385
15949
  return dispatchActivitySetProgress(action, options, deps);
15386
15950
  }
15387
- if (action.kind === "dates-batch") {
15951
+ if (action.kind === DISPATCH_ACTION_KIND.DATES_BATCH) {
15388
15952
  return dispatchDatesBatch(action, options, deps);
15389
15953
  }
15390
- if (action.kind === "bulk-edit") {
15954
+ if (action.kind === DISPATCH_ACTION_KIND.BULK_EDIT) {
15391
15955
  return dispatchBulkEdit(action, options, deps);
15392
15956
  }
15393
- if (action.kind === "selection-toggle") {
15957
+ if (action.kind === DISPATCH_ACTION_KIND.SELECTION_TOGGLE) {
15394
15958
  return dispatchSelectionToggle(action, selectionDeps(deps));
15395
15959
  }
15396
- if (action.kind === "selection-replace") {
15960
+ if (action.kind === DISPATCH_ACTION_KIND.SELECTION_REPLACE) {
15397
15961
  return dispatchSelectionReplace(action, selectionDeps(deps));
15398
15962
  }
15399
- if (action.kind === "visibility-set") {
15963
+ if (action.kind === DISPATCH_ACTION_KIND.VISIBILITY_SET) {
15400
15964
  return dispatchVisibilitySet(action, selectionDeps(deps));
15401
15965
  }
15402
- if (action.kind === "filter-set") {
15966
+ if (action.kind === DISPATCH_ACTION_KIND.FILTER_SET) {
15403
15967
  return dispatchFilterSet(action, {
15404
15968
  adapter: deps.adapter,
15405
15969
  hoursPerDay: deps.sector.hoursPerDay
15406
15970
  });
15407
15971
  }
15408
- if (action.kind === "sort-set") {
15972
+ if (action.kind === DISPATCH_ACTION_KIND.SORT_SET) {
15409
15973
  return dispatchSortSet(action, { adapter: deps.adapter });
15410
15974
  }
15411
- if (action.kind === "sir-sync") {
15975
+ if (action.kind === DISPATCH_ACTION_KIND.SIR_SYNC) {
15412
15976
  return dispatchSirSync(action, deps);
15413
15977
  }
15414
- if (action.kind === "activity-lookahead-sync") {
15978
+ if (action.kind === DISPATCH_ACTION_KIND.ACTIVITY_LOOKAHEAD_SYNC) {
15415
15979
  return dispatchActivityLookaheadSync(action, options, deps);
15416
15980
  }
15417
- if (action.kind === "inline-edit" && (action.column === COLUMN.CUSTOM_PREDECESSORS || action.column === COLUMN.CUSTOM_SUCESSORS)) {
15981
+ if (action.kind === DISPATCH_ACTION_KIND.ACTIVITY_LOOKAHEAD_CONVERT) {
15982
+ return dispatchActivityLookaheadConvert(action, options, deps);
15983
+ }
15984
+ if (action.kind === DISPATCH_ACTION_KIND.INLINE_EDIT && (action.column === COLUMN.CUSTOM_PREDECESSORS || action.column === COLUMN.CUSTOM_SUCESSORS)) {
15418
15985
  return dispatchInlineEditLinks(action, options, deps);
15419
15986
  }
15420
- if (action.kind !== "inline-edit") {
15987
+ if (action.kind !== DISPATCH_ACTION_KIND.INLINE_EDIT) {
15421
15988
  return assertNever(
15422
15989
  action,
15423
15990
  `[ScheduleCore] dispatch kind "${action.kind}" not supported yet`
@@ -15444,7 +16011,7 @@ function coerceActivityFieldValue(field, value) {
15444
16011
 
15445
16012
  // src/calendar/adapter.ts
15446
16013
  function createWorkCalendarAdapter(instance, options = {}) {
15447
- const defaultUnit = options.defaultUnit ?? "hour";
16014
+ const defaultUnit = options.defaultUnit ?? CALENDAR_UNIT.HOUR;
15448
16015
  return {
15449
16016
  getCalendar(calendarId) {
15450
16017
  const calendar = instance.getCalendar(String(calendarId));
@@ -18248,90 +18815,6 @@ function collectDescendantIdsBFS(adapter, rootId) {
18248
18815
  return result;
18249
18816
  }
18250
18817
 
18251
- // src/internal/state/write-capture.ts
18252
- var WriteCapture = class {
18253
- _journal = null;
18254
- begin() {
18255
- this._journal = {
18256
- dirty: /* @__PURE__ */ new Set(),
18257
- before: /* @__PURE__ */ new Map(),
18258
- ops: [],
18259
- linkFieldCaptured: /* @__PURE__ */ new Set(),
18260
- correlativeBefore: /* @__PURE__ */ new Map(),
18261
- scheduledBefore: /* @__PURE__ */ new Map(),
18262
- progressFallbackBefore: /* @__PURE__ */ new Map()
18263
- };
18264
- }
18265
- peek() {
18266
- return this._journal;
18267
- }
18268
- end() {
18269
- this._journal = null;
18270
- }
18271
- note(key, current) {
18272
- const journal = this._journal;
18273
- if (!journal) return;
18274
- if (!journal.before.has(key))
18275
- journal.before.set(key, cloneCoreActivity(current));
18276
- journal.dirty.add(key);
18277
- }
18278
- noteInsert(activityId) {
18279
- this._journal?.ops.push({ kind: "insert", activityId });
18280
- }
18281
- noteRemove(activityId, current) {
18282
- this._journal?.ops.push({
18283
- kind: "remove",
18284
- activityId,
18285
- before: cloneCoreActivity(current)
18286
- });
18287
- }
18288
- noteLinkAdd(linkId) {
18289
- this._journal?.ops.push({ kind: "link-add", linkId });
18290
- }
18291
- noteLinkRemove(linkId, current) {
18292
- this._journal?.ops.push({
18293
- kind: "link-remove",
18294
- linkId,
18295
- before: cloneLink(current)
18296
- });
18297
- }
18298
- noteCorrelativeBefore(activityId, before) {
18299
- const journal = this._journal;
18300
- if (!journal || journal.correlativeBefore.has(activityId)) return;
18301
- journal.correlativeBefore.set(activityId, before);
18302
- }
18303
- noteScheduledBefore(activityId, current) {
18304
- const journal = this._journal;
18305
- if (!journal) return;
18306
- const beforeImage = cloneCoreActivity(current);
18307
- if (!journal.scheduledBefore.has(activityId)) {
18308
- journal.scheduledBefore.set(activityId, beforeImage);
18309
- }
18310
- if (!journal.before.has(activityId)) {
18311
- journal.before.set(activityId, beforeImage);
18312
- }
18313
- journal.dirty.add(activityId);
18314
- }
18315
- noteLinkField(linkId, current) {
18316
- const journal = this._journal;
18317
- if (!journal || journal.linkFieldCaptured.has(linkId)) return;
18318
- journal.linkFieldCaptured.add(linkId);
18319
- journal.ops.push({
18320
- kind: "link-field",
18321
- linkId,
18322
- before: cloneLink(current)
18323
- });
18324
- }
18325
- noteProgressFallback(activityId, current) {
18326
- const journal = this._journal;
18327
- if (!journal || journal.progressFallbackBefore.has(activityId)) return;
18328
- journal.progressFallbackBefore.set(activityId, current);
18329
- }
18330
- };
18331
- function cloneLink(link) {
18332
- return { ...link };
18333
- }
18334
-
18335
18818
  // src/internal/state/calendar-calculator.ts
18336
18819
  var CalendarCalculator = class {
18337
18820
  _cache = {
@@ -18985,9 +19468,9 @@ var ScheduleState = class _ScheduleState {
18985
19468
  this._reInsertRemovedActivities(ops);
18986
19469
  this._reAddRemovedLinks(ops);
18987
19470
  this._restoreLinkFields(ops);
18988
- this._restoreCorrelatives(correlativeBefore);
18989
19471
  this._restoreActivityFields(scheduledBefore);
18990
19472
  this._restoreActivityFields(before);
19473
+ this._restoreCorrelatives(correlativeBefore);
18991
19474
  this._restoreProgressFallbacks(progressFallbackBefore);
18992
19475
  if (this._viewStateBefore !== null) {
18993
19476
  this._viewState.restore(this._viewStateBefore);
@@ -19018,24 +19501,33 @@ var ScheduleState = class _ScheduleState {
19018
19501
  }
19019
19502
  _undoLinkAdds(ops) {
19020
19503
  for (const op of ops)
19021
- if (op.kind === "link-add") this._detachLink(op.linkId);
19504
+ if (op.kind === WRITE_OPERATION_KIND.LINK_ADD) {
19505
+ this._detachLink(op.linkId);
19506
+ }
19022
19507
  }
19023
19508
  _undoInserts(ops) {
19024
19509
  for (const op of ops)
19025
- if (op.kind === "insert") this._activities.delete(op.activityId);
19510
+ if (op.kind === WRITE_OPERATION_KIND.INSERT) {
19511
+ this._activities.delete(op.activityId);
19512
+ }
19026
19513
  }
19027
19514
  _reInsertRemovedActivities(ops) {
19028
19515
  for (const op of ops)
19029
- if (op.kind === "remove") this._activities.set(op.activityId, op.before);
19516
+ if (op.kind === WRITE_OPERATION_KIND.REMOVE) {
19517
+ this._activities.set(op.activityId, op.before);
19518
+ }
19030
19519
  }
19031
19520
  _reAddRemovedLinks(ops) {
19032
19521
  for (const op of ops)
19033
- if (op.kind === "link-remove") this._attachLink(op.before);
19522
+ if (op.kind === WRITE_OPERATION_KIND.LINK_REMOVE) {
19523
+ this._attachLink(op.before);
19524
+ }
19034
19525
  }
19035
19526
  _restoreLinkFields(ops) {
19036
19527
  for (const op of ops)
19037
- if (op.kind === "link-field" && this._links.has(op.linkId))
19528
+ if (op.kind === WRITE_OPERATION_KIND.LINK_FIELD && this._links.has(op.linkId)) {
19038
19529
  this._links.set(op.linkId, op.before);
19530
+ }
19039
19531
  }
19040
19532
  _restoreActivityFields(before) {
19041
19533
  for (const [id, snapshot] of before) {
@@ -19202,7 +19694,8 @@ function withoutDerivedFields(entry, derivedFields) {
19202
19694
  ([field]) => !derivedFields.has(field)
19203
19695
  )
19204
19696
  );
19205
- if (entry.kind === "updated" && Object.keys(fields).length === 0) return null;
19697
+ if (entry.kind === ENTITY_CHANGE_KIND.UPDATED && Object.keys(fields).length === 0)
19698
+ return null;
19206
19699
  return {
19207
19700
  ...entry,
19208
19701
  ...entry.fields === void 0 ? {} : { fields },
@@ -19215,7 +19708,7 @@ function buildHistoryChangeSet(changes) {
19215
19708
  after: null
19216
19709
  }));
19217
19710
  const linksWithoutAfter = changes.links.map((entry) => withoutDerivedFields(entry, DERIVED_LINK_FIELDS)).filter((entry) => entry !== null);
19218
- const source = changes.source.kind === "activity-batch" ? { ...changes.source, items: [], links: [] } : changes.source;
19711
+ const source = changes.source.kind === ACTIVITY_BATCH_ACTION_KIND ? { ...changes.source, items: [], links: [] } : changes.source;
19219
19712
  return cloneDomainValue({
19220
19713
  ...changes,
19221
19714
  source,
@@ -19247,12 +19740,12 @@ function captureCreatedSnapshots(state, changeSet) {
19247
19740
  const afterSnap = /* @__PURE__ */ new Map();
19248
19741
  const afterLinks = /* @__PURE__ */ new Map();
19249
19742
  for (const ch of changeSet.activities) {
19250
- if (ch.kind !== "created") continue;
19743
+ if (ch.kind !== ENTITY_CHANGE_KIND.CREATED) continue;
19251
19744
  const live = state.getActivity(String(ch.id));
19252
19745
  if (live) afterSnap.set(String(ch.id), structuredCloneActivity(live));
19253
19746
  }
19254
19747
  for (const ch of changeSet.links) {
19255
- if (ch.kind === "deleted") continue;
19748
+ if (ch.kind === ENTITY_CHANGE_KIND.DELETED) continue;
19256
19749
  const live = state.getLink(String(ch.id));
19257
19750
  if (live) afterLinks.set(String(ch.id), { ...live });
19258
19751
  }
@@ -19264,7 +19757,7 @@ function computeCoalesceKey(action) {
19264
19757
  return `inline-edit:${String(action.activityId)}:${action.column}`;
19265
19758
  }
19266
19759
  function isSimpleInlineEntry(e) {
19267
- return e.changeSet.activities.length === 1 && e.changeSet.activities[0]?.kind === "updated" && e.changeSet.links.length === 0 && !e.beforeSnap?.size && !e.afterSnap?.size;
19760
+ return e.changeSet.activities.length === 1 && e.changeSet.activities[0]?.kind === ENTITY_CHANGE_KIND.UPDATED && e.changeSet.links.length === 0 && !e.beforeSnap?.size && !e.afterSnap?.size;
19268
19761
  }
19269
19762
  function canCoalesce(top, next) {
19270
19763
  if (!isSimpleInlineEntry(top) || !isSimpleInlineEntry(next)) return false;
@@ -19293,19 +19786,29 @@ function mergeCoalesced(top, next) {
19293
19786
  };
19294
19787
  return buildUndoEntry(changeSet);
19295
19788
  }
19789
+ var DISPATCH_HISTORY_POLICY = {
19790
+ RECORD: "record",
19791
+ SKIP: "skip",
19792
+ CHECKPOINT_ON_SUCCESS: "checkpoint-on-success"
19793
+ };
19794
+ var CHANGE_SET_SIDE = {
19795
+ BEFORE: "before",
19796
+ AFTER: "after"
19797
+ };
19296
19798
  function getDispatchHistoryPolicy(action) {
19297
19799
  if (action.kind === DISPATCH_ACTION_KIND.PERSISTENCE_ACKNOWLEDGE) {
19298
- return "checkpoint-on-success";
19800
+ return DISPATCH_HISTORY_POLICY.CHECKPOINT_ON_SUCCESS;
19299
19801
  }
19300
19802
  if (action.kind === DISPATCH_ACTION_KIND.SIR_SYNC || action.kind === DISPATCH_ACTION_KIND.CALENDAR_RECONCILE || action.kind === DISPATCH_ACTION_KIND.ACTIVITY_LOOKAHEAD_SYNC || action.kind === DISPATCH_ACTION_KIND.BASELINE_APPLY || action.kind === DISPATCH_ACTION_KIND.PONDERATOR_CRITERION_SET || action.kind === DISPATCH_ACTION_KIND.STATUS_CRITERIA_SET || action.kind === DISPATCH_ACTION_KIND.ACTIVITY_CLIPBOARD_CLEAR || action.kind === DISPATCH_ACTION_KIND.ACTIVITY_COPY || action.kind === DISPATCH_ACTION_KIND.SELECTION_TOGGLE || action.kind === DISPATCH_ACTION_KIND.SELECTION_REPLACE || action.kind === DISPATCH_ACTION_KIND.VISIBILITY_SET || action.kind === DISPATCH_ACTION_KIND.FILTER_SET || action.kind === DISPATCH_ACTION_KIND.SORT_SET) {
19301
- return "skip";
19803
+ return DISPATCH_HISTORY_POLICY.SKIP;
19302
19804
  }
19303
- return "record";
19805
+ return DISPATCH_HISTORY_POLICY.RECORD;
19304
19806
  }
19305
19807
  function needsResync(entry) {
19306
19808
  for (const change of entry.changeSet.activities) {
19307
- if (change.kind === "created" || change.kind === "deleted") return true;
19308
- if (change.kind === "updated" && change.fields && COLUMN.CUSTOM_ID in change.fields)
19809
+ if (change.kind === ENTITY_CHANGE_KIND.CREATED || change.kind === ENTITY_CHANGE_KIND.DELETED)
19810
+ return true;
19811
+ if (change.kind === ENTITY_CHANGE_KIND.UPDATED && change.fields && COLUMN.CUSTOM_ID in change.fields)
19309
19812
  return true;
19310
19813
  }
19311
19814
  return false;
@@ -19315,33 +19818,41 @@ function buildInverseChangeSet(state, entry, side) {
19315
19818
  const links = [];
19316
19819
  for (const change of entry.changeSet.activities) {
19317
19820
  const activityId = String(change.id);
19318
- if (change.kind === "updated") {
19821
+ if (change.kind === ENTITY_CHANGE_KIND.UPDATED) {
19319
19822
  const snapshot = state.getActivity(activityId);
19320
19823
  activities.push({
19321
19824
  id: activityId,
19322
- kind: "updated",
19825
+ kind: ENTITY_CHANGE_KIND.UPDATED,
19323
19826
  fields: historyFields(change.fields, side),
19324
19827
  after: snapshot ? structuredCloneActivity(snapshot) : null
19325
19828
  });
19326
- } else if (change.kind === "deleted") {
19327
- if (side === "before") {
19829
+ } else if (change.kind === ENTITY_CHANGE_KIND.DELETED) {
19830
+ if (side === CHANGE_SET_SIDE.BEFORE) {
19328
19831
  const snapshot = state.getActivity(activityId);
19329
19832
  activities.push({
19330
19833
  id: activityId,
19331
- kind: "created",
19834
+ kind: ENTITY_CHANGE_KIND.CREATED,
19332
19835
  after: snapshot ? structuredCloneActivity(snapshot) : null
19333
19836
  });
19334
19837
  } else {
19335
- activities.push({ id: activityId, kind: "deleted", after: null });
19838
+ activities.push({
19839
+ id: activityId,
19840
+ kind: ENTITY_CHANGE_KIND.DELETED,
19841
+ after: null
19842
+ });
19336
19843
  }
19337
19844
  } else {
19338
- if (side === "before") {
19339
- activities.push({ id: activityId, kind: "deleted", after: null });
19845
+ if (side === CHANGE_SET_SIDE.BEFORE) {
19846
+ activities.push({
19847
+ id: activityId,
19848
+ kind: ENTITY_CHANGE_KIND.DELETED,
19849
+ after: null
19850
+ });
19340
19851
  } else {
19341
19852
  const snapshot = state.getActivity(activityId);
19342
19853
  activities.push({
19343
19854
  id: activityId,
19344
- kind: "created",
19855
+ kind: ENTITY_CHANGE_KIND.CREATED,
19345
19856
  after: snapshot ? structuredCloneActivity(snapshot) : null
19346
19857
  });
19347
19858
  }
@@ -19349,44 +19860,52 @@ function buildInverseChangeSet(state, entry, side) {
19349
19860
  }
19350
19861
  for (const change of entry.changeSet.links) {
19351
19862
  const linkId = String(change.id);
19352
- if (change.kind === "updated") {
19863
+ if (change.kind === ENTITY_CHANGE_KIND.UPDATED) {
19353
19864
  const lk = state.getLink(linkId);
19354
19865
  links.push({
19355
19866
  id: linkId,
19356
- kind: "updated",
19867
+ kind: ENTITY_CHANGE_KIND.UPDATED,
19357
19868
  fields: historyFields(change.fields, side),
19358
19869
  after: lk ? snapshotToLink(lk) : null
19359
19870
  });
19360
- } else if (change.kind === "deleted") {
19361
- if (side === "before") {
19871
+ } else if (change.kind === ENTITY_CHANGE_KIND.DELETED) {
19872
+ if (side === CHANGE_SET_SIDE.BEFORE) {
19362
19873
  const lk = state.getLink(linkId);
19363
19874
  links.push({
19364
19875
  id: linkId,
19365
- kind: "created",
19876
+ kind: ENTITY_CHANGE_KIND.CREATED,
19366
19877
  after: lk ? snapshotToLink(lk) : null
19367
19878
  });
19368
19879
  } else {
19369
- links.push({ id: linkId, kind: "deleted", after: null });
19880
+ links.push({
19881
+ id: linkId,
19882
+ kind: ENTITY_CHANGE_KIND.DELETED,
19883
+ after: null
19884
+ });
19370
19885
  }
19371
19886
  } else {
19372
- if (side === "before") {
19373
- links.push({ id: linkId, kind: "deleted", after: null });
19887
+ if (side === CHANGE_SET_SIDE.BEFORE) {
19888
+ links.push({
19889
+ id: linkId,
19890
+ kind: ENTITY_CHANGE_KIND.DELETED,
19891
+ after: null
19892
+ });
19374
19893
  } else {
19375
19894
  const lk = state.getLink(linkId);
19376
19895
  links.push({
19377
19896
  id: linkId,
19378
- kind: "created",
19897
+ kind: ENTITY_CHANGE_KIND.CREATED,
19379
19898
  after: lk ? snapshotToLink(lk) : null
19380
19899
  });
19381
19900
  }
19382
19901
  }
19383
19902
  }
19384
19903
  const viewState = (entry.changeSet.viewState ?? []).map(
19385
- (change) => side === "before" ? invertViewStateChange(change) : change
19904
+ (change) => side === CHANGE_SET_SIDE.BEFORE ? invertViewStateChange(change) : change
19386
19905
  );
19387
19906
  return {
19388
19907
  source: {
19389
- kind: side === "before" ? CHANGE_SET_SOURCE_KIND.UNDO : CHANGE_SET_SOURCE_KIND.REDO
19908
+ kind: side === CHANGE_SET_SIDE.BEFORE ? CHANGE_SET_SOURCE_KIND.UNDO : CHANGE_SET_SOURCE_KIND.REDO
19390
19909
  },
19391
19910
  activities,
19392
19911
  links,
@@ -19401,7 +19920,7 @@ function historyFields(fields, side) {
19401
19920
  return Object.fromEntries(
19402
19921
  Object.entries(fields).map(([field, values]) => [
19403
19922
  field,
19404
- side === "before" ? {
19923
+ side === CHANGE_SET_SIDE.BEFORE ? {
19405
19924
  before: cloneDomainValue(values.after),
19406
19925
  after: cloneDomainValue(values.before)
19407
19926
  } : {
@@ -19432,26 +19951,26 @@ function changeSetIsSubstantive(cs) {
19432
19951
  return cs.activities.length > 0 || cs.links.length > 0 || (cs.viewState?.length ?? 0) > 0 || (cs.effects?.length ?? 0) > 0;
19433
19952
  }
19434
19953
  function applyUndo(state, entry) {
19435
- applyChangeSetSide(state, entry, "before");
19954
+ applyChangeSetSide(state, entry, CHANGE_SET_SIDE.BEFORE);
19436
19955
  }
19437
19956
  function applyRedo(state, entry) {
19438
- applyChangeSetSide(state, entry, "after");
19957
+ applyChangeSetSide(state, entry, CHANGE_SET_SIDE.AFTER);
19439
19958
  }
19440
19959
  function applyChangeSetSide(state, entry, side) {
19441
19960
  const cs = entry.changeSet;
19442
19961
  for (const ch of cs.activities) {
19443
- if (ch.kind === "updated") {
19962
+ if (ch.kind === ENTITY_CHANGE_KIND.UPDATED) {
19444
19963
  if (!ch.fields) continue;
19445
19964
  for (const [field, fieldValue] of Object.entries(ch.fields)) {
19446
19965
  setActivityFieldDynamic(
19447
19966
  state,
19448
19967
  ch.id,
19449
19968
  field,
19450
- side === "before" ? fieldValue.before : fieldValue.after
19969
+ side === CHANGE_SET_SIDE.BEFORE ? fieldValue.before : fieldValue.after
19451
19970
  );
19452
19971
  }
19453
- } else if (ch.kind === "deleted") {
19454
- if (side === "before") {
19972
+ } else if (ch.kind === ENTITY_CHANGE_KIND.DELETED) {
19973
+ if (side === CHANGE_SET_SIDE.BEFORE) {
19455
19974
  const snap = entry.beforeSnap?.get(String(ch.id));
19456
19975
  if (!snap) {
19457
19976
  throw new Error(
@@ -19463,7 +19982,7 @@ function applyChangeSetSide(state, entry, side) {
19463
19982
  state.removeActivity(String(ch.id));
19464
19983
  }
19465
19984
  } else {
19466
- if (side === "before") {
19985
+ if (side === CHANGE_SET_SIDE.BEFORE) {
19467
19986
  state.removeActivity(String(ch.id));
19468
19987
  } else {
19469
19988
  const snap = entry.afterSnap?.get(String(ch.id));
@@ -19477,13 +19996,13 @@ function applyChangeSetSide(state, entry, side) {
19477
19996
  }
19478
19997
  }
19479
19998
  for (const ch of cs.links) {
19480
- if (ch.kind === "updated") {
19999
+ if (ch.kind === ENTITY_CHANGE_KIND.UPDATED) {
19481
20000
  if (!ch.fields) continue;
19482
20001
  if (Object.hasOwn(ch.fields, "source") || Object.hasOwn(ch.fields, "target")) {
19483
- const snapshot = side === "before" ? entry.beforeLinks?.get(String(ch.id)) : entry.afterLinks?.get(String(ch.id));
20002
+ const snapshot = side === CHANGE_SET_SIDE.BEFORE ? entry.beforeLinks?.get(String(ch.id)) : entry.afterLinks?.get(String(ch.id));
19484
20003
  if (!snapshot) {
19485
20004
  throw new Error(
19486
- `${side === "before" ? "undo" : "redo"}: missing link snapshot for ${ch.id}`
20005
+ `${side === CHANGE_SET_SIDE.BEFORE ? "undo" : "redo"}: missing link snapshot for ${ch.id}`
19487
20006
  );
19488
20007
  }
19489
20008
  state.removeLink(String(ch.id));
@@ -19495,11 +20014,11 @@ function applyChangeSetSide(state, entry, side) {
19495
20014
  state,
19496
20015
  String(ch.id),
19497
20016
  field,
19498
- side === "before" ? fv.before : fv.after
20017
+ side === CHANGE_SET_SIDE.BEFORE ? fv.before : fv.after
19499
20018
  );
19500
20019
  }
19501
- } else if (ch.kind === "deleted") {
19502
- if (side === "before") {
20020
+ } else if (ch.kind === ENTITY_CHANGE_KIND.DELETED) {
20021
+ if (side === CHANGE_SET_SIDE.BEFORE) {
19503
20022
  const lk = entry.beforeLinks?.get(String(ch.id));
19504
20023
  if (!lk) {
19505
20024
  throw new Error(
@@ -19511,7 +20030,7 @@ function applyChangeSetSide(state, entry, side) {
19511
20030
  state.removeLink(String(ch.id));
19512
20031
  }
19513
20032
  } else {
19514
- if (side === "before") {
20033
+ if (side === CHANGE_SET_SIDE.BEFORE) {
19515
20034
  state.removeLink(String(ch.id));
19516
20035
  } else {
19517
20036
  const lk = entry.afterLinks?.get(String(ch.id));
@@ -19528,17 +20047,17 @@ function applyChangeSetSide(state, entry, side) {
19528
20047
  if (change.checked) {
19529
20048
  state.setChecked(
19530
20049
  change.activityId,
19531
- side === "before" ? change.checked.before : change.checked.after
20050
+ side === CHANGE_SET_SIDE.BEFORE ? change.checked.before : change.checked.after
19532
20051
  );
19533
20052
  }
19534
20053
  if (change.visible) {
19535
20054
  state.setVisible(
19536
20055
  change.activityId,
19537
- side === "before" ? change.visible.before : change.visible.after
20056
+ side === CHANGE_SET_SIDE.BEFORE ? change.visible.before : change.visible.after
19538
20057
  );
19539
20058
  }
19540
20059
  }
19541
- const progressFallbacks = side === "before" ? entry.progressFallbackBefore : entry.progressFallbackAfter;
20060
+ const progressFallbacks = side === CHANGE_SET_SIDE.BEFORE ? entry.progressFallbackBefore : entry.progressFallbackAfter;
19542
20061
  for (const [activityId, value] of progressFallbacks ?? []) {
19543
20062
  state.setProgressFallback(activityId, value);
19544
20063
  }
@@ -19675,11 +20194,11 @@ function collectResequencedParents(changes, parentOf) {
19675
20194
  };
19676
20195
  for (const change of changes.activities) {
19677
20196
  const activityId = String(change.id);
19678
- if (change.kind === "created") {
20197
+ if (change.kind === ENTITY_CHANGE_KIND.CREATED) {
19679
20198
  addParentOf(activityId);
19680
20199
  continue;
19681
20200
  }
19682
- if (change.kind === "deleted") {
20201
+ if (change.kind === ENTITY_CHANGE_KIND.DELETED) {
19683
20202
  const deletedFields = change.fields;
19684
20203
  if (deletedFields && "parentId" in deletedFields) {
19685
20204
  touched.add(parentKeyOf2(deletedFields.parentId?.before));
@@ -19742,56 +20261,62 @@ function buildStateSnapshot(activities, links, calendars, baseCalendars = []) {
19742
20261
  };
19743
20262
  }
19744
20263
 
20264
+ // src/boundary/save/field-policy.ts
20265
+ var SAVE_FIELD_POLICY = {
20266
+ TRACKED: "tracked",
20267
+ IGNORED: "ignored"
20268
+ };
20269
+
19745
20270
  // src/boundary/save/activity-changes.ts
19746
20271
  var ACTIVITY_SAVE_FIELD_POLICY = {
19747
- id: "ignored",
19748
- proplannerId: "ignored",
19749
- parentId: "tracked",
19750
- name: "tracked",
19751
- description: "tracked",
19752
- type: "tracked",
19753
- startDate: "tracked",
19754
- endDate: "tracked",
19755
- durationHours: "tracked",
19756
- constraintType: "tracked",
19757
- constraintDate: "tracked",
19758
- autoScheduling: "tracked",
19759
- calendarId: "tracked",
19760
- assignedDefaultCalendar: "ignored",
19761
- dateOrigin: "tracked",
19762
- progress: "tracked",
19763
- cost: "tracked",
19764
- usedCost: "tracked",
19765
- realCost: "tracked",
19766
- workHours: "tracked",
19767
- realWorkHours: "tracked",
19768
- ponderator: "tracked",
19769
- hasCustomPonderator: "tracked",
19770
- correlativeId: "tracked",
19771
- uniqueCorrelativeId: "tracked",
19772
- customId: "tracked",
19773
- subcontractId: "tracked",
19774
- isLookahead: "tracked",
19775
- hasLookaheadTasks: "ignored",
19776
- newActivityIds: "tracked",
19777
- hasNewActivities: "tracked",
19778
- isNewActivity: "ignored",
19779
- pendingRequestIds: "ignored",
19780
- responsableIds: "tracked",
19781
- tagIds: "tracked",
19782
- baselinePoints: "ignored",
19783
- baselineSnapshot: "ignored",
19784
- recursiveDurationHours: "ignored",
19785
- isCritical: "ignored",
19786
- freeSlackHours: "ignored",
19787
- calendarDuration: "ignored",
19788
- expectedProgress: "ignored",
19789
- expectedProgressBaseline: "ignored",
19790
- status: "ignored",
19791
- criticalPath: "ignored"
20272
+ id: SAVE_FIELD_POLICY.IGNORED,
20273
+ proplannerId: SAVE_FIELD_POLICY.IGNORED,
20274
+ parentId: SAVE_FIELD_POLICY.TRACKED,
20275
+ name: SAVE_FIELD_POLICY.TRACKED,
20276
+ description: SAVE_FIELD_POLICY.TRACKED,
20277
+ type: SAVE_FIELD_POLICY.TRACKED,
20278
+ startDate: SAVE_FIELD_POLICY.TRACKED,
20279
+ endDate: SAVE_FIELD_POLICY.TRACKED,
20280
+ durationHours: SAVE_FIELD_POLICY.TRACKED,
20281
+ constraintType: SAVE_FIELD_POLICY.TRACKED,
20282
+ constraintDate: SAVE_FIELD_POLICY.TRACKED,
20283
+ autoScheduling: SAVE_FIELD_POLICY.TRACKED,
20284
+ calendarId: SAVE_FIELD_POLICY.TRACKED,
20285
+ assignedDefaultCalendar: SAVE_FIELD_POLICY.IGNORED,
20286
+ dateOrigin: SAVE_FIELD_POLICY.TRACKED,
20287
+ progress: SAVE_FIELD_POLICY.TRACKED,
20288
+ cost: SAVE_FIELD_POLICY.TRACKED,
20289
+ usedCost: SAVE_FIELD_POLICY.TRACKED,
20290
+ realCost: SAVE_FIELD_POLICY.TRACKED,
20291
+ workHours: SAVE_FIELD_POLICY.TRACKED,
20292
+ realWorkHours: SAVE_FIELD_POLICY.TRACKED,
20293
+ ponderator: SAVE_FIELD_POLICY.TRACKED,
20294
+ hasCustomPonderator: SAVE_FIELD_POLICY.TRACKED,
20295
+ correlativeId: SAVE_FIELD_POLICY.TRACKED,
20296
+ uniqueCorrelativeId: SAVE_FIELD_POLICY.TRACKED,
20297
+ customId: SAVE_FIELD_POLICY.TRACKED,
20298
+ subcontractId: SAVE_FIELD_POLICY.TRACKED,
20299
+ isLookahead: SAVE_FIELD_POLICY.TRACKED,
20300
+ hasLookaheadTasks: SAVE_FIELD_POLICY.IGNORED,
20301
+ newActivityIds: SAVE_FIELD_POLICY.TRACKED,
20302
+ hasNewActivities: SAVE_FIELD_POLICY.TRACKED,
20303
+ isNewActivity: SAVE_FIELD_POLICY.IGNORED,
20304
+ pendingRequestIds: SAVE_FIELD_POLICY.IGNORED,
20305
+ responsableIds: SAVE_FIELD_POLICY.TRACKED,
20306
+ tagIds: SAVE_FIELD_POLICY.TRACKED,
20307
+ baselinePoints: SAVE_FIELD_POLICY.IGNORED,
20308
+ baselineSnapshot: SAVE_FIELD_POLICY.IGNORED,
20309
+ recursiveDurationHours: SAVE_FIELD_POLICY.IGNORED,
20310
+ isCritical: SAVE_FIELD_POLICY.IGNORED,
20311
+ freeSlackHours: SAVE_FIELD_POLICY.IGNORED,
20312
+ calendarDuration: SAVE_FIELD_POLICY.IGNORED,
20313
+ expectedProgress: SAVE_FIELD_POLICY.IGNORED,
20314
+ expectedProgressBaseline: SAVE_FIELD_POLICY.IGNORED,
20315
+ status: SAVE_FIELD_POLICY.IGNORED,
20316
+ criticalPath: SAVE_FIELD_POLICY.IGNORED
19792
20317
  };
19793
20318
  var PERSISTABLE_ACTIVITY_FIELDS = Object.keys(ACTIVITY_SAVE_FIELD_POLICY).filter((field) => {
19794
- return ACTIVITY_SAVE_FIELD_POLICY[field] === "tracked";
20319
+ return ACTIVITY_SAVE_FIELD_POLICY[field] === SAVE_FIELD_POLICY.TRACKED;
19795
20320
  });
19796
20321
  var DATE_FIELDS2 = /* @__PURE__ */ new Set([
19797
20322
  "startDate",
@@ -19850,19 +20375,19 @@ function idArrayEquals(current, saved) {
19850
20375
 
19851
20376
  // src/boundary/save/link-changes.ts
19852
20377
  var LINK_SAVE_FIELD_POLICY = {
19853
- id: "ignored",
19854
- source: "tracked",
19855
- target: "tracked",
19856
- type: "tracked",
19857
- lag: "tracked",
19858
- freeSlackHours: "ignored",
19859
- isCritical: "ignored",
19860
- ganttId: "ignored",
19861
- sectorId: "ignored",
19862
- proplannerId: "ignored"
20378
+ id: SAVE_FIELD_POLICY.IGNORED,
20379
+ source: SAVE_FIELD_POLICY.TRACKED,
20380
+ target: SAVE_FIELD_POLICY.TRACKED,
20381
+ type: SAVE_FIELD_POLICY.TRACKED,
20382
+ lag: SAVE_FIELD_POLICY.TRACKED,
20383
+ freeSlackHours: SAVE_FIELD_POLICY.IGNORED,
20384
+ isCritical: SAVE_FIELD_POLICY.IGNORED,
20385
+ ganttId: SAVE_FIELD_POLICY.IGNORED,
20386
+ sectorId: SAVE_FIELD_POLICY.IGNORED,
20387
+ proplannerId: SAVE_FIELD_POLICY.IGNORED
19863
20388
  };
19864
20389
  var TRACKED_LINK_FIELDS = Object.keys(LINK_SAVE_FIELD_POLICY).filter((field) => {
19865
- return LINK_SAVE_FIELD_POLICY[field] === "tracked";
20390
+ return LINK_SAVE_FIELD_POLICY[field] === SAVE_FIELD_POLICY.TRACKED;
19866
20391
  });
19867
20392
  function linkChangedSince(baseline, current) {
19868
20393
  return TRACKED_LINK_FIELDS.some(
@@ -20223,24 +20748,24 @@ var WORKING_DAY_TRUE_VALUES = /* @__PURE__ */ new Set([
20223
20748
  "true"
20224
20749
  ]);
20225
20750
  var DEFAULT_ACTIVITY_CRETER = ACTIVITY_PONDERATOR_CRITERION.DURATION;
20226
- var DEFAULT_CONSTRAINT_TYPE = "asap";
20751
+ var DEFAULT_CONSTRAINT_TYPE = CONSTRAINT_TYPE.ASAP;
20227
20752
  var CONSTRAINT_LABEL_MAP = {
20228
- ASAP: "asap",
20229
- ALAP: "alap",
20230
- SNET: "snet",
20231
- SNLT: "snlt",
20232
- FNET: "fnet",
20233
- FNLT: "fnlt",
20234
- MSO: "mso",
20235
- MFO: "mfo",
20236
- "AS SOON AS POSSIBLE": "asap",
20237
- "AS LATE AS POSSIBLE": "alap",
20238
- "START NO EARLIER THAN": "snet",
20239
- "START NO LATER THAN": "snlt",
20240
- "FINISH NO EARLIER THAN": "fnet",
20241
- "FINISH NO LATER THAN": "fnlt",
20242
- "MUST START ON": "mso",
20243
- "MUST FINISH ON": "mfo"
20753
+ ASAP: CONSTRAINT_TYPE.ASAP,
20754
+ ALAP: CONSTRAINT_TYPE.ALAP,
20755
+ SNET: CONSTRAINT_TYPE.SNET,
20756
+ SNLT: CONSTRAINT_TYPE.SNLT,
20757
+ FNET: CONSTRAINT_TYPE.FNET,
20758
+ FNLT: CONSTRAINT_TYPE.FNLT,
20759
+ MSO: CONSTRAINT_TYPE.MSO,
20760
+ MFO: CONSTRAINT_TYPE.MFO,
20761
+ "AS SOON AS POSSIBLE": CONSTRAINT_TYPE.ASAP,
20762
+ "AS LATE AS POSSIBLE": CONSTRAINT_TYPE.ALAP,
20763
+ "START NO EARLIER THAN": CONSTRAINT_TYPE.SNET,
20764
+ "START NO LATER THAN": CONSTRAINT_TYPE.SNLT,
20765
+ "FINISH NO EARLIER THAN": CONSTRAINT_TYPE.FNET,
20766
+ "FINISH NO LATER THAN": CONSTRAINT_TYPE.FNLT,
20767
+ "MUST START ON": CONSTRAINT_TYPE.MSO,
20768
+ "MUST FINISH ON": CONSTRAINT_TYPE.MFO
20244
20769
  };
20245
20770
 
20246
20771
  // src/boundary/backend/normalize-activity.ts
@@ -20253,13 +20778,19 @@ function normalizeActivities(rawActivities, context) {
20253
20778
  });
20254
20779
  forceRootProjectToRoot(activities);
20255
20780
  const activityIds = new Set(activities.map((activity) => activity.id));
20256
- reparentOrphansToRoot(activities, activityIds, context.reporter);
20781
+ reparentOrphansToRoot(
20782
+ activities,
20783
+ activityIds,
20784
+ context.reporter,
20785
+ context.recordDiagnostic
20786
+ );
20257
20787
  return { activities, activityIds, hiddenIds };
20258
20788
  }
20259
- function parseConstraintLabel(label, reporter) {
20789
+ function parseConstraintLabel(label, reporter, recordDiagnostic, activityId) {
20260
20790
  if (!label) return null;
20261
20791
  const normalized2 = CONSTRAINT_LABEL_MAP[label.toUpperCase()];
20262
20792
  if (normalized2 === void 0) {
20793
+ recordDiagnostic(LOAD_DIAGNOSTIC_CODE.UNKNOWN_CONSTRAINT, activityId);
20263
20794
  reporter.warn(
20264
20795
  `[parseFromBackend] unknown constraint label "${label}" \u2014 defaulting to "asap"`
20265
20796
  );
@@ -20267,9 +20798,14 @@ function parseConstraintLabel(label, reporter) {
20267
20798
  }
20268
20799
  return normalized2;
20269
20800
  }
20270
- function resolveConstraint(raw, reporter) {
20271
- const constraintType = parseConstraintLabel(raw.constraint, reporter);
20272
- const constraintTakesDate = constraintType !== "asap" && constraintType !== "alap";
20801
+ function resolveConstraint(raw, reporter, recordDiagnostic) {
20802
+ const constraintType = parseConstraintLabel(
20803
+ raw.constraint,
20804
+ reporter,
20805
+ recordDiagnostic,
20806
+ String(raw.unique_id)
20807
+ );
20808
+ const constraintTakesDate = constraintType !== CONSTRAINT_TYPE.ASAP && constraintType !== CONSTRAINT_TYPE.ALAP;
20273
20809
  const constraintDate = constraintTakesDate && raw.constraint_date ? parseBackendDate(raw.constraint_date) : null;
20274
20810
  return { constraintType, constraintDate };
20275
20811
  }
@@ -20324,9 +20860,14 @@ function parseCriticality(raw, reporter) {
20324
20860
  );
20325
20861
  return false;
20326
20862
  }
20327
- function parseBaselinePoints(raw, reporter) {
20863
+ function parseBaselinePoints(raw, reporter, recordDiagnostic, activityId) {
20328
20864
  if (!Array.isArray(raw)) return [];
20329
- return raw.map((point) => normalizeBaselinePoint(point, reporter)).filter((point) => point !== null);
20865
+ return raw.map(
20866
+ (point) => normalizeBaselinePoint(point, reporter, {
20867
+ record: recordDiagnostic,
20868
+ sampleId: activityId
20869
+ })
20870
+ ).filter((point) => point !== null);
20330
20871
  }
20331
20872
  function parseActivity(raw, context) {
20332
20873
  const calendarId = resolveCalendarId2(
@@ -20338,9 +20879,10 @@ function parseActivity(raw, context) {
20338
20879
  const progress = Number(raw.progress);
20339
20880
  const { constraintType, constraintDate } = resolveConstraint(
20340
20881
  raw,
20341
- context.reporter
20882
+ context.reporter,
20883
+ context.recordDiagnostic
20342
20884
  );
20343
- const isMilestone = raw.type === "milestone";
20885
+ const isMilestone = raw.type === ACTIVITY_TYPE.MILESTONE;
20344
20886
  const startDate = parseBackendDate(raw.start_date);
20345
20887
  const endDate = isMilestone ? startDate : parseBackendDate(raw.end_date);
20346
20888
  const durationDays = isMilestone ? 0 : Number(raw.duration);
@@ -20381,7 +20923,12 @@ function parseActivity(raw, context) {
20381
20923
  pendingRequestIds: parseIdList(raw.pendingRequests),
20382
20924
  responsableIds: parseIdList(raw.responsables),
20383
20925
  tagIds: parseIdList(raw.tags),
20384
- baselinePoints: parseBaselinePoints(raw.baseline_points, context.reporter),
20926
+ baselinePoints: parseBaselinePoints(
20927
+ raw.baseline_points,
20928
+ context.reporter,
20929
+ context.recordDiagnostic,
20930
+ String(raw.unique_id)
20931
+ ),
20385
20932
  baselineSnapshot: null,
20386
20933
  recursiveDurationHours: durationToHours(
20387
20934
  Number(raw.sumOfDurationRecursively ?? 0),
@@ -20405,17 +20952,18 @@ function normalizeCustomId(raw) {
20405
20952
  }
20406
20953
  function forceRootProjectToRoot(activities) {
20407
20954
  const rootProject = activities.find(
20408
- (activity) => activity.correlativeId === 0 && activity.type === "project"
20955
+ (activity) => activity.correlativeId === 0 && activity.type === ACTIVITY_TYPE.PROJECT
20409
20956
  );
20410
20957
  if (rootProject) rootProject.parentId = null;
20411
20958
  }
20412
- function reparentOrphansToRoot(activities, ids, reporter) {
20959
+ function reparentOrphansToRoot(activities, ids, reporter, recordDiagnostic) {
20413
20960
  for (const activity of activities) {
20414
20961
  if (activity.parentId === null) continue;
20415
20962
  if (!ids.has(activity.parentId)) {
20416
20963
  reporter.warn(
20417
20964
  `[parseFromBackend] activity "${activity.id}" references unknown parent "${activity.parentId}" \u2014 re-parenting to root (null)`
20418
20965
  );
20966
+ recordDiagnostic(LOAD_DIAGNOSTIC_CODE.ORPHAN_ACTIVITY, activity.id);
20419
20967
  activity.parentId = null;
20420
20968
  }
20421
20969
  }
@@ -20639,14 +21187,11 @@ function isMissingValue(value) {
20639
21187
  }
20640
21188
 
20641
21189
  // src/boundary/backend/normalize-link.ts
20642
- function isLinkTypeCode(value) {
20643
- return value === "0" || value === "1" || value === "2" || value === "3";
20644
- }
20645
21190
  function resolveLinkType(rawType) {
20646
21191
  if (typeof rawType !== "string") return null;
20647
21192
  const fromLabel = parseLinkTypeCode(rawType);
20648
21193
  if (fromLabel) return fromLabel;
20649
- if (isLinkTypeCode(rawType)) return rawType;
21194
+ if (isLinkType(rawType)) return rawType;
20650
21195
  return null;
20651
21196
  }
20652
21197
  function normalizePersistedLinkId(rawId) {
@@ -20665,13 +21210,17 @@ function normalizeLinks(rawLinks, context) {
20665
21210
  parseLink(rawLink, context.knownActivityIds, context.hoursPerDay)
20666
21211
  );
20667
21212
  } catch (parseError2) {
21213
+ context.recordDiagnostic(
21214
+ LOAD_DIAGNOSTIC_CODE.INVALID_LINK,
21215
+ String(rawLink.unique_id ?? rawLink.id)
21216
+ );
20668
21217
  context.reporter.warn(
20669
21218
  "[parseFromBackend] dropping invalid link",
20670
21219
  parseError2
20671
21220
  );
20672
21221
  }
20673
21222
  }
20674
- return dedupeLinksBySignature(parsedLinks);
21223
+ return dedupeLinksBySignature(parsedLinks, context.recordDiagnostic);
20675
21224
  }
20676
21225
  function parseLink(link, activityIds, hoursPerDay) {
20677
21226
  const id = String(link.unique_id ?? link.id);
@@ -20709,12 +21258,19 @@ function parseLink(link, activityIds, hoursPerDay) {
20709
21258
  ...proplannerId === void 0 ? {} : { proplannerId }
20710
21259
  };
20711
21260
  }
20712
- function dedupeLinksBySignature(links) {
21261
+ function dedupeLinksBySignature(links, recordDiagnostic) {
20713
21262
  const bySignature = /* @__PURE__ */ new Map();
20714
21263
  for (const link of links) {
20715
21264
  const signature = `${link.source}-${link.target}-${link.type}`;
20716
21265
  const existing = bySignature.get(signature);
20717
- if (!existing || linkIdAsNumber(link) > linkIdAsNumber(existing)) {
21266
+ if (!existing) {
21267
+ bySignature.set(signature, link);
21268
+ continue;
21269
+ }
21270
+ const incomingWins = linkIdAsNumber(link) > linkIdAsNumber(existing);
21271
+ const discarded = incomingWins ? existing : link;
21272
+ recordDiagnostic(LOAD_DIAGNOSTIC_CODE.DUPLICATE_LINK, discarded.id);
21273
+ if (incomingWins) {
20718
21274
  bySignature.set(signature, link);
20719
21275
  }
20720
21276
  }
@@ -20772,7 +21328,7 @@ function parseSector(sector) {
20772
21328
  }
20773
21329
 
20774
21330
  // src/boundary/backend/parse-from-backend.ts
20775
- function parseFromBackend(input, reporter = noopReporter) {
21331
+ function parseFromBackend(input, reporter = noopReporter, recordDiagnostic = noopLoadDiagnosticRecorder) {
20776
21332
  const sector = parseSector(input.sector);
20777
21333
  const { calendars, baseCalendars, knownCalendarIds, defaultCalendarId } = normalizeCalendars(
20778
21334
  input.calendars,
@@ -20786,13 +21342,15 @@ function parseFromBackend(input, reporter = noopReporter) {
20786
21342
  knownCalendarIds,
20787
21343
  defaultCalendarId,
20788
21344
  hoursPerDay: sector.hoursPerDay,
20789
- reporter
21345
+ reporter,
21346
+ recordDiagnostic
20790
21347
  }
20791
21348
  );
20792
21349
  const links = normalizeLinks(input.links, {
20793
21350
  knownActivityIds: activityIds,
20794
21351
  hoursPerDay: sector.hoursPerDay,
20795
- reporter
21352
+ reporter,
21353
+ recordDiagnostic
20796
21354
  });
20797
21355
  return {
20798
21356
  sector,
@@ -21008,6 +21566,11 @@ function maxSuffixFromArray(suffixes) {
21008
21566
  }
21009
21567
 
21010
21568
  // src/generators/custom-id/generation-strategies.ts
21569
+ var GENERATION_STRATEGY = {
21570
+ PARENT_CONVERSION: "parentConversion",
21571
+ PASTE_REFERENCE: "pasteReference",
21572
+ NO_CONTEXT: "noContext"
21573
+ };
21011
21574
  function parentConversionStrategy(defaultPrefix) {
21012
21575
  return { prefix: defaultPrefix, baseSuffix: null };
21013
21576
  }
@@ -21023,12 +21586,12 @@ function noContextStrategy(defaultPrefix) {
21023
21586
  }
21024
21587
  function selectGenerationStrategy(customId, useActivityCustomIdAsReference) {
21025
21588
  if (isParentConversionCase(customId, useActivityCustomIdAsReference)) {
21026
- return "parentConversion";
21589
+ return GENERATION_STRATEGY.PARENT_CONVERSION;
21027
21590
  }
21028
21591
  if (isPasteOrLineReferenceCase(customId, useActivityCustomIdAsReference)) {
21029
- return "pasteReference";
21592
+ return GENERATION_STRATEGY.PASTE_REFERENCE;
21030
21593
  }
21031
- return "noContext";
21594
+ return GENERATION_STRATEGY.NO_CONTEXT;
21032
21595
  }
21033
21596
 
21034
21597
  // src/generators/custom-id/tracker.ts
@@ -21341,15 +21904,15 @@ var CustomIdTracker = class _CustomIdTracker {
21341
21904
  customId
21342
21905
  );
21343
21906
  let capturedNextSuffix = null;
21344
- if (strategyKey === "parentConversion" && this.prefixMap.has(prefix)) {
21907
+ if (strategyKey === GENERATION_STRATEGY.PARENT_CONVERSION && this.prefixMap.has(prefix)) {
21345
21908
  this._ensureFreshBounds(prefix);
21346
21909
  const currentMax = this.prefixMap.get(prefix).max;
21347
21910
  capturedNextSuffix = addToSuffix(currentMax, this.suffixIncrement);
21348
21911
  }
21349
- if (strategyKey === "parentConversion") {
21912
+ if (strategyKey === GENERATION_STRATEGY.PARENT_CONVERSION) {
21350
21913
  this.releaseCustomId(customId);
21351
21914
  }
21352
- const effectiveBaseSuffix = strategyKey === "parentConversion" && capturedNextSuffix ? capturedNextSuffix : baseSuffix;
21915
+ const effectiveBaseSuffix = strategyKey === GENERATION_STRATEGY.PARENT_CONVERSION && capturedNextSuffix ? capturedNextSuffix : baseSuffix;
21353
21916
  const nextSuffix = this.getNextAvailableSuffix(prefix, effectiveBaseSuffix);
21354
21917
  if (nextSuffix === null) {
21355
21918
  const generatedId2 = this._generateDefaultCustomId();
@@ -21365,9 +21928,9 @@ var CustomIdTracker = class _CustomIdTracker {
21365
21928
  }
21366
21929
  _applyGenerationStrategy(strategyKey, customId) {
21367
21930
  switch (strategyKey) {
21368
- case "parentConversion":
21931
+ case GENERATION_STRATEGY.PARENT_CONVERSION:
21369
21932
  return parentConversionStrategy(this.defaultPrefix);
21370
- case "pasteReference":
21933
+ case GENERATION_STRATEGY.PASTE_REFERENCE:
21371
21934
  return pasteReferenceStrategy(customId, this.suffixIncrement);
21372
21935
  default:
21373
21936
  return noContextStrategy(this.defaultPrefix);
@@ -21483,7 +22046,7 @@ function buildComparator(order, context) {
21483
22046
  function demoteChildlessSummaries(state) {
21484
22047
  const idsToDemote = [];
21485
22048
  state.forEachActivity((activity, activityId) => {
21486
- if (activity.type !== "project") return;
22049
+ if (activity.type !== ACTIVITY_TYPE.PROJECT) return;
21487
22050
  if (state.getChildren(String(activityId)).length === 0) {
21488
22051
  idsToDemote.push(String(activityId));
21489
22052
  }
@@ -21601,7 +22164,7 @@ function normalizeLoadedConstraintDates(state) {
21601
22164
  const type = activity.constraintType;
21602
22165
  if (!type || !activity.constraintDate) return;
21603
22166
  const constraintDate = activity.constraintDate;
21604
- if (activity.type === "milestone" && (constraintDate.getUTCHours() !== 0 || constraintDate.getUTCMinutes() !== 0)) {
22167
+ if (activity.type === ACTIVITY_TYPE.MILESTONE && (constraintDate.getUTCHours() !== 0 || constraintDate.getUTCMinutes() !== 0)) {
21605
22168
  return;
21606
22169
  }
21607
22170
  const calendar = state.calendarReader.getCalendar(
@@ -21617,7 +22180,7 @@ function normalizeLoadedConstraintDates(state) {
21617
22180
  }
21618
22181
  function normalizeMilestoneConstraintDatesForDisplay(state) {
21619
22182
  state.forEachActivity((activity) => {
21620
- if (activity.type !== "milestone") return;
22183
+ if (activity.type !== ACTIVITY_TYPE.MILESTONE) return;
21621
22184
  const type = activity.constraintType;
21622
22185
  if (!type || !activity.constraintDate) return;
21623
22186
  const calendar = state.calendarReader.getCalendar(
@@ -21643,6 +22206,7 @@ function initializeCore(input) {
21643
22206
  const initializedAt = clock?.() ?? null;
21644
22207
  const loadNow = initializedAt ? endOfLocalDay(initializedAt) : null;
21645
22208
  const reporter = input.reporter ?? noopReporter;
22209
+ const loadDiagnostics = createLoadDiagnosticsCollector();
21646
22210
  const parsed2 = parseFromBackend(
21647
22211
  {
21648
22212
  sector: input.sector,
@@ -21651,7 +22215,8 @@ function initializeCore(input) {
21651
22215
  calendars: input.calendars,
21652
22216
  baseCalendars: input.baseCalendars
21653
22217
  },
21654
- reporter
22218
+ reporter,
22219
+ loadDiagnostics.record
21655
22220
  );
21656
22221
  const sector = parsed2.sector;
21657
22222
  sector.statusCriteria = resolveStatusCriteria(input.statusCriteria);
@@ -21691,7 +22256,8 @@ function initializeCore(input) {
21691
22256
  input.baselinePoints,
21692
22257
  loadNow,
21693
22258
  reporter,
21694
- defaultBaseCalendarId
22259
+ defaultBaseCalendarId,
22260
+ loadDiagnostics.record
21695
22261
  );
21696
22262
  }
21697
22263
  const initPromise = runInitialPasses({
@@ -21713,6 +22279,7 @@ function initializeCore(input) {
21713
22279
  baseCalendars,
21714
22280
  clock,
21715
22281
  reporter,
22282
+ loadDiagnostics: loadDiagnostics.snapshot,
21716
22283
  initPromise
21717
22284
  };
21718
22285
  }
@@ -21774,18 +22341,22 @@ function entityChanges(target, source) {
21774
22341
  const before = sourceById.get(id);
21775
22342
  const after = targetById.get(id);
21776
22343
  if (after === void 0) {
21777
- changes.push({ id, kind: "deleted", after: null });
22344
+ changes.push({ id, kind: ENTITY_CHANGE_KIND.DELETED, after: null });
21778
22345
  continue;
21779
22346
  }
21780
22347
  if (before === void 0) {
21781
- changes.push({ id, kind: "created", after: cloneDomainValue(after) });
22348
+ changes.push({
22349
+ id,
22350
+ kind: ENTITY_CHANGE_KIND.CREATED,
22351
+ after: cloneDomainValue(after)
22352
+ });
21782
22353
  continue;
21783
22354
  }
21784
22355
  const fields = changedFields(before, after);
21785
22356
  if (Object.keys(fields).length > 0) {
21786
22357
  changes.push({
21787
22358
  id,
21788
- kind: "updated",
22359
+ kind: ENTITY_CHANGE_KIND.UPDATED,
21789
22360
  fields,
21790
22361
  after: cloneDomainValue(after)
21791
22362
  });
@@ -22000,8 +22571,8 @@ function acknowledgesPersistence(action) {
22000
22571
  }
22001
22572
  function changesRequireFilterProjectionRebuild(changes) {
22002
22573
  for (const change of changes.activities) {
22003
- if (change.kind === "deleted") return true;
22004
- const hasMovedParent = change.kind === "updated" && change.fields !== void 0 && "parentId" in change.fields;
22574
+ if (change.kind === ENTITY_CHANGE_KIND.DELETED) return true;
22575
+ const hasMovedParent = change.kind === ENTITY_CHANGE_KIND.UPDATED && change.fields !== void 0 && "parentId" in change.fields;
22005
22576
  if (hasMovedParent) return true;
22006
22577
  }
22007
22578
  return false;
@@ -22053,6 +22624,7 @@ var ScheduleCore = class _ScheduleCore {
22053
22624
  _undo = new UndoRecorder();
22054
22625
  _opQueue = Promise.resolve();
22055
22626
  _scheduleRevision = 0;
22627
+ _stateRevision = 0;
22056
22628
  _pendingScheduleRevision = 0;
22057
22629
  _criticalPathRevision = -1;
22058
22630
  _activeCriticalPath = null;
@@ -22078,7 +22650,8 @@ var ScheduleCore = class _ScheduleCore {
22078
22650
  ),
22079
22651
  baseCalendars: cloneDomainValue(source.coreRuntime.baseCalendars),
22080
22652
  clock: source.coreRuntime.clock,
22081
- reporter: source.coreRuntime.reporter
22653
+ reporter: source.coreRuntime.reporter,
22654
+ loadDiagnostics: source.coreRuntime.loadDiagnostics
22082
22655
  };
22083
22656
  this._activityClipboard.value = cloneDomainValue(
22084
22657
  source._activityClipboard.value
@@ -22086,6 +22659,7 @@ var ScheduleCore = class _ScheduleCore {
22086
22659
  this._undo = source._undo.fork();
22087
22660
  this._saveTracker = source._saveTracker.fork();
22088
22661
  this._scheduleRevision = source._scheduleRevision;
22662
+ this._stateRevision = source._stateRevision;
22089
22663
  this._pendingScheduleRevision = source._scheduleRevision;
22090
22664
  this._criticalPathRevision = source._criticalPathRevision;
22091
22665
  this._initPromise = Promise.resolve();
@@ -22108,7 +22682,8 @@ var ScheduleCore = class _ScheduleCore {
22108
22682
  initialized.calendars.map((calendar) => [calendar.id, calendar])
22109
22683
  ),
22110
22684
  baseCalendars: initialized.baseCalendars,
22111
- reporter: initialized.reporter
22685
+ reporter: initialized.reporter,
22686
+ loadDiagnostics: initialized.loadDiagnostics
22112
22687
  };
22113
22688
  this._initPromise = initialized.initPromise.then(() => {
22114
22689
  if (this._status === SCHEDULE_CORE_STATUS.DESTROYED) return;
@@ -22173,6 +22748,11 @@ var ScheduleCore = class _ScheduleCore {
22173
22748
  getSector() {
22174
22749
  return cloneDomainValue(this.coreRuntime.sector);
22175
22750
  }
22751
+ /** Returns immutable data-quality diagnostics collected during loading. */
22752
+ getLoadDiagnostics() {
22753
+ this.assertReady();
22754
+ return this.coreRuntime.loadDiagnostics();
22755
+ }
22176
22756
  /**
22177
22757
  * Reads a defensive activity snapshot from a ready schedule.
22178
22758
  *
@@ -22442,6 +23022,10 @@ var ScheduleCore = class _ScheduleCore {
22442
23022
  getScheduleRevision() {
22443
23023
  return this._scheduleRevision;
22444
23024
  }
23025
+ /** @returns The monotonic canonical-state revision without a readiness guard. */
23026
+ getStateRevision() {
23027
+ return this._stateRevision;
23028
+ }
22445
23029
  /** @returns The undo-history boundary for an external save checkpoint. */
22446
23030
  capturePersistenceHistoryBoundary() {
22447
23031
  this.assertReady();
@@ -22551,6 +23135,21 @@ var ScheduleCore = class _ScheduleCore {
22551
23135
  const admitted = this._beginScheduleMutation(action);
22552
23136
  return this._enqueue(() => this._dispatchInner(action, options, admitted));
22553
23137
  }
23138
+ /** Builds the defensive canonical conversion intent without mutating state. */
23139
+ planLookaheadConversion(input) {
23140
+ this.assertReady();
23141
+ return buildLookaheadConversionPlan(input, {
23142
+ adapter: this.coreRuntime.state,
23143
+ stateRevision: this._stateRevision
23144
+ });
23145
+ }
23146
+ /** Applies one revision-guarded conversion through the serialized dispatcher. */
23147
+ applyLookaheadConversion(input) {
23148
+ return this.dispatch({
23149
+ ...input,
23150
+ kind: DISPATCH_ACTION_KIND.ACTIVITY_LOOKAHEAD_CONVERT
23151
+ });
23152
+ }
22554
23153
  async _dispatchInner(action, options = {}, admitted = false) {
22555
23154
  let changedState = false;
22556
23155
  try {
@@ -22601,6 +23200,7 @@ var ScheduleCore = class _ScheduleCore {
22601
23200
  customIdTracker: this.coreRuntime.customIdTracker,
22602
23201
  reporter: this.coreRuntime.reporter,
22603
23202
  activityClipboard: this._activityClipboard,
23203
+ stateRevision: this._stateRevision,
22604
23204
  defaultBaseCalendarId: this.coreRuntime.baseCalendars.find(
22605
23205
  (calendar) => calendar.baseDefault
22606
23206
  )?.id ?? null,
@@ -22618,7 +23218,7 @@ var ScheduleCore = class _ScheduleCore {
22618
23218
  this.coreRuntime.state.endWriteCapture();
22619
23219
  this.coreRuntime.customIdTracker.commitCustomIdTransaction();
22620
23220
  }
22621
- if (result.ok && historyPolicy === "record" && changeSetIsSubstantive(result.changes)) {
23221
+ if (result.ok && historyPolicy === DISPATCH_HISTORY_POLICY.RECORD && changeSetIsSubstantive(result.changes)) {
22622
23222
  const created = captureCreatedSnapshots(
22623
23223
  this.coreRuntime.state,
22624
23224
  result.changes
@@ -22644,7 +23244,7 @@ var ScheduleCore = class _ScheduleCore {
22644
23244
  );
22645
23245
  }
22646
23246
  if (result.ok) {
22647
- if (historyPolicy === "checkpoint-on-success") {
23247
+ if (historyPolicy === DISPATCH_HISTORY_POLICY.CHECKPOINT_ON_SUCCESS) {
22648
23248
  if (action.kind !== DISPATCH_ACTION_KIND.PERSISTENCE_ACKNOWLEDGE) {
22649
23249
  throw new Error(
22650
23250
  "checkpoint-on-success requires persistence acknowledge"
@@ -22686,7 +23286,9 @@ var ScheduleCore = class _ScheduleCore {
22686
23286
  }
22687
23287
  result = this._withReappliedViewState(action, result);
22688
23288
  if (!result.ok) return { result, changedState: false };
22689
- if (dispatchChangesSchedulingState(action) && changeSetIsSubstantive(result.changes)) {
23289
+ const hasSubstantiveChanges = changeSetIsSubstantive(result.changes);
23290
+ if (hasSubstantiveChanges) this._stateRevision++;
23291
+ if (dispatchChangesSchedulingState(action) && hasSubstantiveChanges) {
22690
23292
  this._recordScheduleMutation(
22691
23293
  options.skipAutoSchedule !== true && options.skipCriticalPath !== true && resolveRunCriticalPath(action)
22692
23294
  );
@@ -22761,7 +23363,7 @@ var ScheduleCore = class _ScheduleCore {
22761
23363
  }
22762
23364
  const affectedParents = new Set(resequencedParents);
22763
23365
  for (const change of changes.activities) {
22764
- if (change.kind === "deleted") {
23366
+ if (change.kind === ENTITY_CHANGE_KIND.DELETED) {
22765
23367
  return { ...changes, order: collectBranchOrder(adapter) };
22766
23368
  }
22767
23369
  const parentId = adapter.getParentId(change.id);
@@ -22955,7 +23557,7 @@ var ScheduleCore = class _ScheduleCore {
22955
23557
  const changes = buildInverseChangeSet(
22956
23558
  this.coreRuntime.state,
22957
23559
  entry,
22958
- "before"
23560
+ CHANGE_SET_SIDE.BEFORE
22959
23561
  );
22960
23562
  this._saveTracker.recordChanges(
22961
23563
  changes.activities,
@@ -23012,7 +23614,7 @@ var ScheduleCore = class _ScheduleCore {
23012
23614
  const changes = buildInverseChangeSet(
23013
23615
  this.coreRuntime.state,
23014
23616
  entry,
23015
- "after"
23617
+ CHANGE_SET_SIDE.AFTER
23016
23618
  );
23017
23619
  this._saveTracker.recordChanges(
23018
23620
  changes.activities,
@@ -23073,6 +23675,7 @@ var ScheduleCore = class _ScheduleCore {
23073
23675
  _rollback(generatorSnapshot) {
23074
23676
  try {
23075
23677
  this.coreRuntime.state.restoreFromCapture();
23678
+ this.coreRuntime.scheduler.invalidateAllCaches();
23076
23679
  this.coreRuntime.customIdTracker.rollbackCustomIdTransaction();
23077
23680
  if (generatorSnapshot) {
23078
23681
  this.coreRuntime.activityIdGenerator.restore(generatorSnapshot[0]);
@@ -23133,6 +23736,6 @@ var CREATION_KIND = {
23133
23736
  ROOT: "root"
23134
23737
  };
23135
23738
 
23136
- export { ACTIVITY_BATCH_ACTION_KIND, ACTIVITY_BATCH_MODE, ACTIVITY_DATE_EDGE, ACTIVITY_FIELD, ACTIVITY_PONDERATOR_CRITERION, ACTIVITY_TYPE, CALENDAR_UNIT, CHANGE_SET_SOURCE_KIND, COLUMN, COMPLETED_PROGRESS, CONSTRAINT_TYPE, CONSTRAINT_TYPE_TO_LABEL, CONSTRAINT_WARNING_KIND, CREATION_KIND, DATE_GESTURE_KIND, DEFAULT_HOURS_PER_DAY, DISPATCH_ACTION_KIND, DISPATCH_ACTION_KINDS, DISPATCH_LINK_OPERATION_KIND, DISPATCH_TRACK_EVENT, FILTER_FIELD, FILTER_LOGIC, FILTER_OPERATOR, FILTER_REJECTION_REASON, FILTER_VALUE_KIND, LINK_BATCH_OPERATION_KIND, LINK_CODE_TO_TYPE, LINK_REJECTION_REASON, LINK_RELATIONSHIP, LINK_TYPE, LINK_TYPE_CODE, NEW_ACTIVITY_DEFAULTS, NOT_STARTED_PROGRESS, ORDER_DIRECTION, REJECTION_REASON, ROOT_PARENT_ID, SCHEDULE_CORE_STATUS, SCHEDULE_EFFECT_KIND, SIR_AUTO_REJECT_REASON, STATUS, STATUS_CRITERIA, ScheduleCore, WORK_TIME_DIRECTION, checkNoUpdatedLinks, computeExpectedProgress, createSchedule, expectedProgressFromBaseline, getActiveBaseline, getUnsavedActivities, isRootParent, normalizeParentKey, parseFromBackend, willRunCriticalPath, yieldToBrowser };
23739
+ export { ACTIVITY_BATCH_ACTION_KIND, ACTIVITY_BATCH_MODE, ACTIVITY_DATE_EDGE, ACTIVITY_FIELD, ACTIVITY_PONDERATOR_CRITERION, ACTIVITY_PROGRESS_ORIGIN, ACTIVITY_TYPE, CALENDAR_UNIT, CHANGE_SET_SOURCE_KIND, COLUMN, COMPLETED_PROGRESS, CONSTRAINT_TYPE, CONSTRAINT_TYPE_TO_LABEL, CONSTRAINT_WARNING_KIND, CREATION_KIND, DATE_GESTURE_KIND, DEFAULT_HOURS_PER_DAY, DISPATCH_ACTION_KIND, DISPATCH_ACTION_KINDS, DISPATCH_LINK_OPERATION_KIND, DISPATCH_TRACK_EVENT, ENTITY_CHANGE_KIND, FILTER_FIELD, FILTER_LOGIC, FILTER_OPERATOR, FILTER_REJECTION_REASON, FILTER_VALUE_KIND, LINK_BATCH_OPERATION_KIND, LINK_CODE, LINK_CODE_TO_TYPE, LINK_REJECTION_REASON, LINK_RELATIONSHIP, LINK_TYPE, LINK_TYPE_CODE, NEW_ACTIVITY_DEFAULTS, NOT_STARTED_PROGRESS, ORDER_DIRECTION, REJECTION_REASON, ROOT_PARENT_ID, SCHEDULE_CORE_STATUS, SCHEDULE_EFFECT_KIND, SIR_AUTO_REJECT_REASON, STATUS, STATUS_CRITERIA, ScheduleCore, WORK_TIME_DIRECTION, checkNoUpdatedLinks, computeExpectedProgress, createSchedule, expectedProgressFromBaseline, getActiveBaseline, getUnsavedActivities, isRootParent, normalizeParentKey, parseFromBackend, willRunCriticalPath, yieldToBrowser };
23137
23740
  //# sourceMappingURL=index.js.map
23138
23741
  //# sourceMappingURL=index.js.map