@outbuild-company/schedule-core 1.17.2 → 1.19.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
@@ -289,6 +289,7 @@ var READ_ONLY = {
289
289
  DURATION_BASE: "duration_base",
290
290
  COST_BASE: "cost_base",
291
291
  WORK_BASE: "work_base",
292
+ BASELINE_VARIANCE: "baseline_variance",
292
293
  CALENDAR_DURATION: "calendarDuration",
293
294
  IS_CRITICAL: "is_critical",
294
295
  EARLY_START: "earlyStart",
@@ -351,6 +352,7 @@ var DISPATCH_ACTION_KIND = {
351
352
  SORT_SET: "sort-set",
352
353
  VIEW_ATTRIBUTES_SET: "view-attributes-set",
353
354
  GROUP_SET: "group-set",
355
+ WBS_DEPTH_SET: "wbs-depth-set",
354
356
  SIR_SYNC: "sir-sync",
355
357
  ACTIVITY_LOOKAHEAD_SYNC: "activity-lookahead-sync",
356
358
  SCHEDULE_AUTO_SCHEDULE: "schedule-auto-schedule"
@@ -685,6 +687,12 @@ function createScheduleNamespaces(engine) {
685
687
  kind: DISPATCH_ACTION_KIND.GROUP_SET,
686
688
  group
687
689
  }),
690
+ wbsDepth: () => engine.getWbsDepth(),
691
+ setWbsDepth: (wbsDepth, context = {}) => engine.dispatch({
692
+ ...context,
693
+ kind: DISPATCH_ACTION_KIND.WBS_DEPTH_SET,
694
+ wbsDepth
695
+ }),
688
696
  setVisibility: (activityIds, context = {}) => engine.dispatch({
689
697
  ...context,
690
698
  kind: DISPATCH_ACTION_KIND.VISIBILITY_SET,
@@ -1042,6 +1050,7 @@ var FILTER_FIELD = {
1042
1050
  TOTAL_SLACK_DAYS: "totalSlackDays",
1043
1051
  EXPECTED_PROGRESS_BASELINE: "expectedProgressBaseline",
1044
1052
  BASELINE_DURATION_DAYS: "baselineDurationDays",
1053
+ BASELINE_VARIANCE_DAYS: "baselineVarianceDays",
1045
1054
  BASELINE_COST: "baselineCost",
1046
1055
  BASELINE_WORK_HOURS: "baselineWorkHours",
1047
1056
  EXPECTED_PROGRESS: "expectedProgress",
@@ -1209,6 +1218,10 @@ var FIELD_REGISTRY = {
1209
1218
  valueKind: FILTER_VALUE_KIND.NUMBER,
1210
1219
  extract: (activity) => activity.baselineSnapshot?.durationDays ?? null
1211
1220
  },
1221
+ [FILTER_FIELD.BASELINE_VARIANCE_DAYS]: {
1222
+ valueKind: FILTER_VALUE_KIND.NUMBER,
1223
+ extract: (activity) => activity.baselineVarianceDays
1224
+ },
1212
1225
  [FILTER_FIELD.BASELINE_COST]: {
1213
1226
  valueKind: FILTER_VALUE_KIND.NUMBER,
1214
1227
  extract: (activity) => activity.baselineSnapshot?.cost ?? null
@@ -1299,6 +1312,7 @@ var GROUP_ID_SEPARATOR = ":";
1299
1312
  var UNASSIGNED_GROUP_LABEL = "Unassigned";
1300
1313
  var MINIMUM_GROUP_DEPTH = 1;
1301
1314
  var MINIMUM_GROUP_LEVEL = 1;
1315
+ var FLAT_WBS_DEPTH = 0;
1302
1316
  function buildGroupRowId(attributeKey, valueId) {
1303
1317
  return `${GROUP_ID_PREFIX}${GROUP_ID_SEPARATOR}${attributeKey}${GROUP_ID_SEPARATOR}${valueId}`;
1304
1318
  }
@@ -2276,6 +2290,17 @@ function dispatchGroupSet(action, deps) {
2276
2290
  adapter.setGroup(group);
2277
2291
  return { ok: true, changes: emptyViewChanges(action) };
2278
2292
  }
2293
+ function dispatchWbsDepthSet(action, deps) {
2294
+ const { adapter } = deps;
2295
+ const { wbsDepth } = action;
2296
+ if (wbsDepth !== null) {
2297
+ if (!isFiniteInteger(wbsDepth) || wbsDepth < FLAT_WBS_DEPTH) {
2298
+ return { ok: false, reason: FILTER_REJECTION_REASON.INVALID_VALUE };
2299
+ }
2300
+ }
2301
+ adapter.setWbsDepth(wbsDepth);
2302
+ return { ok: true, changes: emptyViewChanges(action) };
2303
+ }
2279
2304
 
2280
2305
  // src/shared/assert-never.ts
2281
2306
  function assertNever(value, message) {
@@ -2354,7 +2379,8 @@ var ACTIVITY_PROPERTY = {
2354
2379
  CUSTOM_ID: "customId",
2355
2380
  NEW_ACTIVITIES_ARRAY: "newActivityIds",
2356
2381
  HAS_NEW_ACTIVITIES: "hasNewActivities",
2357
- CALENDAR_DURATION: "calendarDuration"};
2382
+ CALENDAR_DURATION: "calendarDuration",
2383
+ BASELINE_VARIANCE_DAYS: "baselineVarianceDays"};
2358
2384
  var LINK_PROPERTY = {
2359
2385
  SOURCE: "source",
2360
2386
  TARGET: "target",
@@ -6286,12 +6312,16 @@ function mergeCorrelativeShiftIntoDiff(diff, correlativeBefore, activityId, live
6286
6312
  after: liveActivity.correlativeId
6287
6313
  };
6288
6314
  }
6315
+ var DERIVED_DISPLAY_FIELDS = [
6316
+ ACTIVITY_PROPERTY.CALENDAR_DURATION,
6317
+ ACTIVITY_PROPERTY.BASELINE_VARIANCE_DAYS
6318
+ ];
6289
6319
  function diffActivity(before, after) {
6290
6320
  const fields = {};
6291
6321
  const beforeRec = before ?? {};
6292
6322
  const afterRec = after;
6293
6323
  const keys = /* @__PURE__ */ new Set([...Object.keys(beforeRec), ...Object.keys(afterRec)]);
6294
- keys.delete(ACTIVITY_PROPERTY.CALENDAR_DURATION);
6324
+ for (const derived of DERIVED_DISPLAY_FIELDS) keys.delete(derived);
6295
6325
  for (const k of keys) {
6296
6326
  if (Object.hasOwn(beforeRec, k) !== Object.hasOwn(afterRec, k) || !fieldValueEqual(beforeRec[k], afterRec[k])) {
6297
6327
  fields[k] = {
@@ -6541,6 +6571,43 @@ function applyStatusPass(state, criteria) {
6541
6571
  return changed;
6542
6572
  }
6543
6573
 
6574
+ // src/propagations/shared/get-visible-baseline.ts
6575
+ function getVisibleBaseline(activity) {
6576
+ const points = activity?.baselinePoints;
6577
+ if (!Array.isArray(points) || points.length === 0) return null;
6578
+ return points.find((point) => point.isVisibleVersion) ?? null;
6579
+ }
6580
+
6581
+ // src/columns/baseline-variance/compute.ts
6582
+ var VARIANCE_DECIMAL_SCALE = 100;
6583
+ var roundToVariancePrecision = (days) => Math.round(days * VARIANCE_DECIMAL_SCALE) / VARIANCE_DECIMAL_SCALE;
6584
+ function computeBaselineVarianceDays(activity, calendars, hoursPerDay) {
6585
+ if (hoursPerDay <= 0) return null;
6586
+ const baselineEnd = getVisibleBaseline(activity)?.endDate;
6587
+ const activityEnd = activity.endDate;
6588
+ if (!baselineEnd || !activityEnd) return null;
6589
+ const finishesLate = activityEnd.getTime() > baselineEnd.getTime();
6590
+ const finishesEarly = baselineEnd.getTime() > activityEnd.getTime();
6591
+ if (!finishesLate && !finishesEarly) return 0;
6592
+ const durationHours = calendars.calculateDuration({
6593
+ startDate: finishesLate ? baselineEnd : activityEnd,
6594
+ endDate: finishesLate ? activityEnd : baselineEnd,
6595
+ task: activity
6596
+ });
6597
+ const magnitude = roundToVariancePrecision(durationHours / hoursPerDay);
6598
+ return finishesLate ? magnitude : -magnitude;
6599
+ }
6600
+ function applyBaselineVariancePass(state, hoursPerDay) {
6601
+ const changed = [];
6602
+ state.forEachActivity((activity, id) => {
6603
+ const variance = computeBaselineVarianceDays(activity, state, hoursPerDay);
6604
+ if (activity.baselineVarianceDays === variance) return;
6605
+ activity.baselineVarianceDays = variance;
6606
+ changed.push(String(id));
6607
+ });
6608
+ return changed;
6609
+ }
6610
+
6544
6611
  // src/critical-path/legacy/shims/moment.js
6545
6612
  function moment(input) {
6546
6613
  const d = input instanceof Date ? new Date(input.getTime()) : input && typeof input === "object" && typeof input.valueOf === "function" ? new Date(input.valueOf()) : new Date(input);
@@ -11165,6 +11232,7 @@ var NON_SCHEDULING_KINDS = /* @__PURE__ */ new Set([
11165
11232
  DISPATCH_ACTION_KIND.SORT_SET,
11166
11233
  DISPATCH_ACTION_KIND.VIEW_ATTRIBUTES_SET,
11167
11234
  DISPATCH_ACTION_KIND.GROUP_SET,
11235
+ DISPATCH_ACTION_KIND.WBS_DEPTH_SET,
11168
11236
  DISPATCH_ACTION_KIND.SIR_SYNC,
11169
11237
  DISPATCH_ACTION_KIND.ACTIVITY_LOOKAHEAD_SYNC,
11170
11238
  DISPATCH_ACTION_KIND.PERSISTENCE_ACKNOWLEDGE,
@@ -11181,7 +11249,8 @@ var PURE_VIEW_STATE_KINDS = /* @__PURE__ */ new Set([
11181
11249
  DISPATCH_ACTION_KIND.FILTER_SET,
11182
11250
  DISPATCH_ACTION_KIND.SORT_SET,
11183
11251
  DISPATCH_ACTION_KIND.VIEW_ATTRIBUTES_SET,
11184
- DISPATCH_ACTION_KIND.GROUP_SET
11252
+ DISPATCH_ACTION_KIND.GROUP_SET,
11253
+ DISPATCH_ACTION_KIND.WBS_DEPTH_SET
11185
11254
  ]);
11186
11255
  function reappliesViewState(action) {
11187
11256
  return !PURE_VIEW_STATE_KINDS.has(action.kind);
@@ -11265,6 +11334,7 @@ var DERIVED_PASS = {
11265
11334
  REAL_WORK: "real-work",
11266
11335
  EXPECTED_PROGRESS: "expected-progress",
11267
11336
  REAL_COST: "real-cost",
11337
+ BASELINE_VARIANCE: "baseline-variance",
11268
11338
  CRITICAL_PATH: "critical-path"
11269
11339
  };
11270
11340
  function resolveDerivedPasses(action, autoSchedule, options) {
@@ -11282,6 +11352,9 @@ function resolveDerivedPasses(action, autoSchedule, options) {
11282
11352
  if (runsLoadRecomputes && resolveRunRealCost(action)) {
11283
11353
  passes.add(DERIVED_PASS.REAL_COST);
11284
11354
  }
11355
+ if (dispatchChangesSchedulingState(action)) {
11356
+ passes.add(DERIVED_PASS.BASELINE_VARIANCE);
11357
+ }
11285
11358
  const runsCriticalPath = runsLoadRecomputes && resolveRunCriticalPath(action) && !options.skipCriticalPath;
11286
11359
  if (runsCriticalPath) passes.add(DERIVED_PASS.CRITICAL_PATH);
11287
11360
  return passes;
@@ -11944,6 +12017,9 @@ async function runDerivedRecomputes(deps, passes, now) {
11944
12017
  if (passes.has(DERIVED_PASS.REAL_COST)) {
11945
12018
  emitRealCost(deps.adapter);
11946
12019
  }
12020
+ if (passes.has(DERIVED_PASS.BASELINE_VARIANCE)) {
12021
+ applyBaselineVariancePass(deps.adapter, deps.sector.hoursPerDay);
12022
+ }
11947
12023
  if (passes.has(DERIVED_PASS.CRITICAL_PATH)) {
11948
12024
  await applyCriticalPath(deps.adapter, deps.sector.hoursPerDay);
11949
12025
  }
@@ -12891,6 +12967,7 @@ var NEW_ACTIVITY_DEFAULTS = Object.freeze({
12891
12967
  tagIds: [],
12892
12968
  baselinePoints: [],
12893
12969
  baselineSnapshot: null,
12970
+ baselineVarianceDays: null,
12894
12971
  recursiveDurationHours: 0,
12895
12972
  isCritical: false,
12896
12973
  freeSlackHours: null,
@@ -16622,6 +16699,7 @@ async function dispatchBaselineApply(action, deps) {
16622
16699
  deps.reporter,
16623
16700
  deps.defaultBaseCalendarId ?? null
16624
16701
  );
16702
+ applyBaselineVariancePass(deps.adapter, deps.sector.hoursPerDay);
16625
16703
  if (activeBaselineSignature(deps) !== activeBaselineBefore) {
16626
16704
  recomputeBaselineWeightedFields(
16627
16705
  deps,
@@ -17062,6 +17140,12 @@ async function performDispatch(action, options, deps) {
17062
17140
  hoursPerDay: deps.sector.hoursPerDay
17063
17141
  });
17064
17142
  }
17143
+ if (action.kind === DISPATCH_ACTION_KIND.WBS_DEPTH_SET) {
17144
+ return dispatchWbsDepthSet(action, {
17145
+ adapter: deps.adapter,
17146
+ hoursPerDay: deps.sector.hoursPerDay
17147
+ });
17148
+ }
17065
17149
  if (action.kind === DISPATCH_ACTION_KIND.SIR_SYNC) {
17066
17150
  return dispatchSirSync(action, deps);
17067
17151
  }
@@ -20201,35 +20285,95 @@ function sortedChildNodes(node, direction) {
20201
20285
  if (direction === ORDER_DIRECTION.DESCENDING) children.reverse();
20202
20286
  return children;
20203
20287
  }
20204
- function emitWbsOrderedActivities(memberActivities, activitiesInVisualOrder, parentOf, rows) {
20205
- const members = new Set(
20288
+ var FIRST_WBS_LEVEL = 1;
20289
+ var WHOLE_WBS = Number.POSITIVE_INFINITY;
20290
+ function activityRow(activity) {
20291
+ return {
20292
+ kind: VISUAL_ROW_KIND.ACTIVITY,
20293
+ activityId: String(activity.id)
20294
+ };
20295
+ }
20296
+ function buildWbsTree(included, activitiesInVisualOrder, parentOf) {
20297
+ const roots = [];
20298
+ const childrenOf = /* @__PURE__ */ new Map();
20299
+ for (const activity of activitiesInVisualOrder) {
20300
+ if (!included.has(String(activity.id))) continue;
20301
+ const parentId = parentOf(activity.id);
20302
+ const parentKey = parentId === null ? null : String(parentId);
20303
+ if (parentKey === null || !included.has(parentKey)) {
20304
+ roots.push(activity);
20305
+ continue;
20306
+ }
20307
+ const siblings = childrenOf.get(parentKey);
20308
+ if (siblings === void 0) childrenOf.set(parentKey, [activity]);
20309
+ else siblings.push(activity);
20310
+ }
20311
+ return { roots, childrenOf };
20312
+ }
20313
+ function emitWbsRows(included, input) {
20314
+ const { roots, childrenOf } = buildWbsTree(
20315
+ included,
20316
+ input.activitiesInVisualOrder,
20317
+ input.parentOf
20318
+ );
20319
+ const cap = input.wbsDepth ?? WHOLE_WBS;
20320
+ const childrenOfActivity = (activity) => childrenOf.get(String(activity.id)) ?? [];
20321
+ const foldToActivities = (siblings) => {
20322
+ const folded = [];
20323
+ const walk = (nodes) => {
20324
+ for (const node of nodes) {
20325
+ const children = childrenOfActivity(node);
20326
+ if (children.length === 0) folded.push(node);
20327
+ else walk(children);
20328
+ }
20329
+ };
20330
+ walk(siblings);
20331
+ return folded;
20332
+ };
20333
+ const emit = (siblings, level) => {
20334
+ if (level > cap) {
20335
+ const folded = foldToActivities(siblings);
20336
+ const ordered = input.comparator === null ? folded : sortSiblingsInOrderMode(
20337
+ folded,
20338
+ input.comparator,
20339
+ input.orderMode,
20340
+ () => false
20341
+ );
20342
+ for (const activity of ordered) input.rows.push(activityRow(activity));
20343
+ return;
20344
+ }
20345
+ for (const activity of siblings) {
20346
+ input.rows.push(activityRow(activity));
20347
+ const children = childrenOfActivity(activity);
20348
+ if (children.length > 0) emit(children, level + 1);
20349
+ }
20350
+ };
20351
+ emit(roots, FIRST_WBS_LEVEL);
20352
+ }
20353
+ function emitWbsOrderedActivities(memberActivities, input) {
20354
+ const included = new Set(
20206
20355
  memberActivities.map((activity) => String(activity.id))
20207
20356
  );
20208
- const included = new Set(members);
20209
- for (const memberId of members) {
20210
- let ancestorId = parentOf(memberId);
20357
+ for (const member of memberActivities) {
20358
+ let ancestorId = input.parentOf(member.id);
20211
20359
  while (ancestorId !== null) {
20212
20360
  included.add(String(ancestorId));
20213
- ancestorId = parentOf(ancestorId);
20361
+ ancestorId = input.parentOf(ancestorId);
20214
20362
  }
20215
20363
  }
20216
- for (const activity of activitiesInVisualOrder) {
20217
- if (!included.has(String(activity.id))) continue;
20218
- rows.push({
20219
- kind: VISUAL_ROW_KIND.ACTIVITY,
20220
- activityId: String(activity.id)
20221
- });
20222
- }
20364
+ emitWbsRows(included, input);
20223
20365
  }
20224
20366
  function emitActivities(node, context) {
20225
20367
  const { rows } = context;
20226
20368
  if (context.group.includeWbs) {
20227
- emitWbsOrderedActivities(
20228
- node.activities,
20229
- context.activitiesInVisualOrder,
20230
- context.parentOf,
20369
+ emitWbsOrderedActivities(node.activities, {
20370
+ activitiesInVisualOrder: context.activitiesInVisualOrder,
20371
+ parentOf: context.parentOf,
20372
+ wbsDepth: context.wbsDepth,
20373
+ comparator: context.comparator,
20374
+ orderMode: context.orderMode,
20231
20375
  rows
20232
- );
20376
+ });
20233
20377
  return;
20234
20378
  }
20235
20379
  for (const activity of sortSiblingsInOrderMode(
@@ -20280,10 +20424,20 @@ function projectVisualRows(input) {
20280
20424
  (activity) => input.isVisible(activity.id)
20281
20425
  );
20282
20426
  if (input.group === null || input.catalog === null) {
20283
- return visibleActivities.map((activity) => ({
20284
- kind: VISUAL_ROW_KIND.ACTIVITY,
20285
- activityId: String(activity.id)
20286
- }));
20427
+ if (input.wbsDepth === null) return visibleActivities.map(activityRow);
20428
+ const rows2 = [];
20429
+ emitWbsRows(
20430
+ new Set(visibleActivities.map((activity) => String(activity.id))),
20431
+ {
20432
+ activitiesInVisualOrder: visibleActivities,
20433
+ parentOf: input.parentOf,
20434
+ wbsDepth: input.wbsDepth,
20435
+ comparator: input.comparator,
20436
+ orderMode: input.orderMode,
20437
+ rows: rows2
20438
+ }
20439
+ );
20440
+ return rows2;
20287
20441
  }
20288
20442
  const { group, catalog } = input;
20289
20443
  const root = buildGroupTree(
@@ -20301,6 +20455,7 @@ function projectVisualRows(input) {
20301
20455
  hasChildren: input.hasChildren,
20302
20456
  comparator: input.comparator,
20303
20457
  orderMode: input.orderMode,
20458
+ wbsDepth: input.wbsDepth,
20304
20459
  secondaryCatalog: input.secondaryCatalog,
20305
20460
  rows
20306
20461
  };
@@ -20314,6 +20469,7 @@ function projectVisualRows(input) {
20314
20469
  var ViewAttributeStore = class _ViewAttributeStore {
20315
20470
  catalogs = /* @__PURE__ */ new Map();
20316
20471
  group = null;
20472
+ wbsDepth = null;
20317
20473
  getCatalog(key) {
20318
20474
  return this.catalogs.get(key) ?? null;
20319
20475
  }
@@ -20333,10 +20489,17 @@ var ViewAttributeStore = class _ViewAttributeStore {
20333
20489
  setGroup(nextGroup) {
20334
20490
  this.group = nextGroup;
20335
20491
  }
20492
+ getWbsDepth() {
20493
+ return this.wbsDepth;
20494
+ }
20495
+ setWbsDepth(nextDepth) {
20496
+ this.wbsDepth = nextDepth;
20497
+ }
20336
20498
  clone() {
20337
20499
  const fork = new _ViewAttributeStore();
20338
20500
  fork.catalogs = new Map(this.catalogs);
20339
20501
  fork.group = this.group === null ? null : cloneDomainValue(this.group);
20502
+ fork.wbsDepth = this.wbsDepth;
20340
20503
  return fork;
20341
20504
  }
20342
20505
  };
@@ -20574,6 +20737,13 @@ var ScheduleState = class _ScheduleState {
20574
20737
  this._viewAttributes.setGroup(nextGroup);
20575
20738
  this.invalidateVisualRows();
20576
20739
  }
20740
+ getWbsDepth() {
20741
+ return this._viewAttributes.getWbsDepth();
20742
+ }
20743
+ setWbsDepth(nextDepth) {
20744
+ this._viewAttributes.setWbsDepth(nextDepth);
20745
+ this.invalidateVisualRows();
20746
+ }
20577
20747
  invalidateVisualRows() {
20578
20748
  this._cache.visualRows = null;
20579
20749
  }
@@ -20596,7 +20766,8 @@ var ScheduleState = class _ScheduleState {
20596
20766
  catalog,
20597
20767
  secondaryCatalog,
20598
20768
  comparator: this.getOrderComparator(),
20599
- orderMode: this.getOrderMode()
20769
+ orderMode: this.getOrderMode(),
20770
+ wbsDepth: this._viewAttributes.getWbsDepth()
20600
20771
  });
20601
20772
  return this._cache.visualRows;
20602
20773
  }
@@ -21193,7 +21364,7 @@ function getDispatchHistoryPolicy(action) {
21193
21364
  if (action.kind === DISPATCH_ACTION_KIND.PERSISTENCE_ACKNOWLEDGE) {
21194
21365
  return DISPATCH_HISTORY_POLICY.CHECKPOINT_ON_SUCCESS;
21195
21366
  }
21196
- 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 || action.kind === DISPATCH_ACTION_KIND.VIEW_ATTRIBUTES_SET || action.kind === DISPATCH_ACTION_KIND.GROUP_SET) {
21367
+ 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 || action.kind === DISPATCH_ACTION_KIND.VIEW_ATTRIBUTES_SET || action.kind === DISPATCH_ACTION_KIND.GROUP_SET || action.kind === DISPATCH_ACTION_KIND.WBS_DEPTH_SET) {
21197
21368
  return DISPATCH_HISTORY_POLICY.SKIP;
21198
21369
  }
21199
21370
  return DISPATCH_HISTORY_POLICY.RECORD;
@@ -21709,6 +21880,7 @@ var ACTIVITY_SAVE_FIELD_POLICY = {
21709
21880
  isCritical: SAVE_FIELD_POLICY.IGNORED,
21710
21881
  freeSlackHours: SAVE_FIELD_POLICY.IGNORED,
21711
21882
  calendarDuration: SAVE_FIELD_POLICY.IGNORED,
21883
+ baselineVarianceDays: SAVE_FIELD_POLICY.IGNORED,
21712
21884
  expectedProgress: SAVE_FIELD_POLICY.IGNORED,
21713
21885
  expectedProgressBaseline: SAVE_FIELD_POLICY.IGNORED,
21714
21886
  status: SAVE_FIELD_POLICY.IGNORED,
@@ -22335,6 +22507,7 @@ function parseActivity(raw, context) {
22335
22507
  isMilestone
22336
22508
  ),
22337
22509
  baselineSnapshot: null,
22510
+ baselineVarianceDays: null,
22338
22511
  recursiveDurationHours: durationToHours(
22339
22512
  Number(raw.sumOfDurationRecursively ?? 0),
22340
22513
  context.hoursPerDay
@@ -23557,6 +23730,7 @@ async function runInitialPasses(deps) {
23557
23730
  applyExpectedProgressLive(state, now);
23558
23731
  applyStatusPass(state, sector.statusCriteria);
23559
23732
  }
23733
+ applyBaselineVariancePass(state, sector.hoursPerDay);
23560
23734
  return;
23561
23735
  }
23562
23736
  const result = await scheduler.schedule({});
@@ -23569,6 +23743,7 @@ async function runInitialPasses(deps) {
23569
23743
  applyExpectedProgressLive(state, now);
23570
23744
  applyStatusPass(state, sector.statusCriteria);
23571
23745
  }
23746
+ applyBaselineVariancePass(state, sector.hoursPerDay);
23572
23747
  }
23573
23748
  function recomputeSkippedLeafEnds(state) {
23574
23749
  state.forEachActivity((activity) => {
@@ -24446,6 +24621,11 @@ var ScheduleCore = class _ScheduleCore {
24446
24621
  this.assertReady();
24447
24622
  return cloneDomainValue(this.coreRuntime.state.getGroup());
24448
24623
  }
24624
+ /** @returns How deep the WBS reaches the screen, or `null` for every level. */
24625
+ getWbsDepth() {
24626
+ this.assertReady();
24627
+ return this.coreRuntime.state.getWbsDepth();
24628
+ }
24449
24629
  /** @returns Whether the parent currently has a direct child. */
24450
24630
  hasChild(parentId) {
24451
24631
  this.assertReady();
@@ -25388,6 +25568,6 @@ var CREATION_KIND = {
25388
25568
  ROOT: "root"
25389
25569
  };
25390
25570
 
25391
- 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, EDIT_ALERT_KEY, EDIT_DENIAL_REASON, ENTITY_CHANGE_KIND, FILTER_FIELD, FILTER_LOGIC, FILTER_OPERATOR, FILTER_REJECTION_REASON, FILTER_VALUE_KIND, GROUP_ID_PREFIX, GROUP_ID_SEPARATOR, LINK_BATCH_OPERATION_KIND, LINK_CODE, LINK_CODE_TO_TYPE, LINK_REJECTION_REASON, LINK_RELATIONSHIP, LINK_TYPE, LINK_TYPE_CODE, MINIMUM_GROUP_DEPTH, MINIMUM_GROUP_LEVEL, NEW_ACTIVITY_DEFAULTS, NOT_STARTED_PROGRESS, ORDER_DIRECTION, ORDER_MODE, REJECTION_REASON, ROOT_PARENT_ID, SCHEDULE_CORE_STATUS, SCHEDULE_EFFECT_KIND, SIR_AUTO_REJECT_REASON, STATUS, STATUS_CRITERIA, ScheduleCore, UNASSIGNED_GROUP_LABEL, UNASSIGNED_VALUE_ID, VIEW_ATTRIBUTE_KIND, VISUAL_ROW_KIND, WORK_TIME_DIRECTION, appendGroupRowId, buildGroupRowId, checkNoUpdatedLinks, computeExpectedProgress, createSchedule, expectedProgressFromBaseline, getActiveBaseline, getUnsavedActivities, isRootParent, isViewAttributeCriterion, isViewAttributeOrderRule, normalizeParentKey, parseFromBackend, willRunCriticalPath, yieldToBrowser };
25571
+ 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, EDIT_ALERT_KEY, EDIT_DENIAL_REASON, ENTITY_CHANGE_KIND, FILTER_FIELD, FILTER_LOGIC, FILTER_OPERATOR, FILTER_REJECTION_REASON, FILTER_VALUE_KIND, FLAT_WBS_DEPTH, GROUP_ID_PREFIX, GROUP_ID_SEPARATOR, LINK_BATCH_OPERATION_KIND, LINK_CODE, LINK_CODE_TO_TYPE, LINK_REJECTION_REASON, LINK_RELATIONSHIP, LINK_TYPE, LINK_TYPE_CODE, MINIMUM_GROUP_DEPTH, MINIMUM_GROUP_LEVEL, NEW_ACTIVITY_DEFAULTS, NOT_STARTED_PROGRESS, ORDER_DIRECTION, ORDER_MODE, REJECTION_REASON, ROOT_PARENT_ID, SCHEDULE_CORE_STATUS, SCHEDULE_EFFECT_KIND, SIR_AUTO_REJECT_REASON, STATUS, STATUS_CRITERIA, ScheduleCore, UNASSIGNED_GROUP_LABEL, UNASSIGNED_VALUE_ID, VIEW_ATTRIBUTE_KIND, VISUAL_ROW_KIND, WORK_TIME_DIRECTION, appendGroupRowId, buildGroupRowId, checkNoUpdatedLinks, computeExpectedProgress, createSchedule, expectedProgressFromBaseline, getActiveBaseline, getUnsavedActivities, isRootParent, isViewAttributeCriterion, isViewAttributeOrderRule, normalizeParentKey, parseFromBackend, willRunCriticalPath, yieldToBrowser };
25392
25572
  //# sourceMappingURL=index.js.map
25393
25573
  //# sourceMappingURL=index.js.map