tods-competition-factory 2.2.31 → 2.2.32-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  function factoryVersion() {
6
- return '2.2.31';
6
+ return '2.2.32-beta.1';
7
7
  }
8
8
 
9
9
  const SINGLES_MATCHUP = 'SINGLES';
@@ -653,6 +653,10 @@ const INCOMPATIBLE_MATCHUP_STATUS = {
653
653
  message: 'Incompatible matchUpStatus',
654
654
  code: 'ERR_INCOMPATIBLE_MATCHUP_STATUS',
655
655
  };
656
+ const PROPAGATED_EXITS_DOWNSTREAM = {
657
+ message: 'Propagated exits downstream',
658
+ code: 'ERR_PROPAGATED_EXITS_DOWNSTREAM',
659
+ };
656
660
  const INVALID_MATCHUP_STATUS = {
657
661
  message: 'Invalid matchUpStatus',
658
662
  code: 'ERR_INVALID_MATCHUP_STATUS',
@@ -1880,38 +1884,85 @@ function decorateResult({ context, result, stack, info }) {
1880
1884
  return result ?? { success: true };
1881
1885
  }
1882
1886
 
1883
- const ANY = 'ANY';
1884
- const MALE = 'MALE';
1885
- const MIXED = 'MIXED';
1886
- const OTHER$3 = 'OTHER';
1887
+ const FEMALE_ABBR = 'F';
1888
+ const OTHER_ABBR = 'O';
1889
+ const MIXED_ABBR = 'X';
1890
+ const MALE_ABBR = 'M';
1891
+ const ANY_ABBR = 'A';
1887
1892
  const FEMALE = 'FEMALE';
1893
+ const OTHER$3 = 'OTHER';
1894
+ const MIXED = 'MIXED';
1895
+ const MALE = 'MALE';
1896
+ const ANY = 'ANY';
1888
1897
  const genderConstants = {
1889
- ANY,
1890
- MALE,
1898
+ FEMALE_ABBR,
1899
+ OTHER_ABBR,
1900
+ MIXED_ABBR,
1901
+ MALE_ABBR,
1902
+ ANY_ABBR,
1891
1903
  FEMALE,
1892
1904
  MIXED,
1893
1905
  OTHER: OTHER$3,
1906
+ MALE,
1907
+ ANY,
1894
1908
  };
1895
1909
 
1910
+ function isFemale(gender) {
1911
+ return [FEMALE, FEMALE_ABBR].includes(gender);
1912
+ }
1913
+
1914
+ function isMale(gender) {
1915
+ return [MALE, MALE_ABBR].includes(gender);
1916
+ }
1917
+
1918
+ function isMixed(gender) {
1919
+ return [MIXED, MIXED_ABBR].includes(gender);
1920
+ }
1921
+
1922
+ function isAny(gender) {
1923
+ return [ANY, ANY_ABBR].includes(gender);
1924
+ }
1925
+
1926
+ function coercedGender(gender) {
1927
+ if (gender) {
1928
+ if (isFemale(gender))
1929
+ return FEMALE;
1930
+ if (isMixed(gender))
1931
+ return MIXED;
1932
+ if (isMale(gender))
1933
+ return MALE;
1934
+ if (isAny(gender))
1935
+ return ANY;
1936
+ }
1937
+ return OTHER$3;
1938
+ }
1939
+
1940
+ function isGendered(gender) {
1941
+ return isFemale(gender) || isMale(gender);
1942
+ }
1943
+
1896
1944
  const mixedGenderError = 'MIXED events can not contain mixed singles or { gender: ANY } collections';
1897
1945
  const anyMixedError = 'events with { gender: ANY } can not contain MIXED singles collections';
1898
1946
  function tieFormatGenderValidityCheck(params) {
1899
1947
  const stack = 'tieFormatGenderValidityCheck';
1900
1948
  const { referenceGender, matchUpType, gender } = params;
1901
- if (referenceGender && gender && [MALE, FEMALE].includes(referenceGender) && referenceGender !== gender)
1949
+ if (referenceGender &&
1950
+ gender &&
1951
+ isGendered(referenceGender) &&
1952
+ coercedGender(referenceGender) !== coercedGender(gender))
1902
1953
  return decorateResult({
1903
1954
  result: { valid: false, error: INVALID_GENDER },
1904
1955
  context: { gender },
1905
1956
  stack,
1906
1957
  });
1907
- if (referenceGender === MIXED && (gender === ANY || (gender === MIXED && matchUpType !== DOUBLES$1))) {
1958
+ if (isMixed(referenceGender) && (isAny(gender) || (isMixed(gender) && matchUpType !== DOUBLES$1))) {
1908
1959
  return decorateResult({
1909
1960
  result: { error: INVALID_GENDER, valid: false },
1910
1961
  info: mixedGenderError,
1911
1962
  stack,
1912
1963
  });
1913
1964
  }
1914
- if (referenceGender === ANY && gender === MIXED && matchUpType !== DOUBLES$1)
1965
+ if (isAny(referenceGender) && isMixed(gender) && matchUpType !== DOUBLES$1)
1915
1966
  return decorateResult({
1916
1967
  result: { error: INVALID_GENDER, valid: false },
1917
1968
  info: anyMixedError,
@@ -12237,7 +12288,67 @@ function getInitialRoundNumber({ drawPosition, matchUps = [] }) {
12237
12288
  return { initialRoundNumber };
12238
12289
  }
12239
12290
 
12240
- function assignDrawPositionBye({ provisionalPositioning, isPositionAction, tournamentRecord, drawDefinition, drawPosition, matchUpsMap, structureId, structure, event, }) {
12291
+ const logColors = {
12292
+ reset: '\x1b[0m',
12293
+ bright: '\x1b[1m',
12294
+ dim: '\x1b[2m',
12295
+ red: '\x1b[31m',
12296
+ brightred: '\x1b[91m',
12297
+ green: '\x1b[32m',
12298
+ brightgreen: '\x1b[92m',
12299
+ yellow: '\x1b[33m',
12300
+ brightyellow: '\x1b[93m',
12301
+ blue: '\x1b[34m',
12302
+ brightblue: '\x1b[94m',
12303
+ lightblue: '\x1b[105m',
12304
+ magenta: '\x1b[35m',
12305
+ brightmagenta: '\x1b[95m',
12306
+ cyan: '\x1b[36m',
12307
+ brightcyan: '\x1b[96m',
12308
+ white: '\x1b[37m',
12309
+ brightwhite: '\x1b[97m',
12310
+ };
12311
+
12312
+ const globalLog = [];
12313
+ function pushGlobalLog(value, devContextOverride) {
12314
+ if (isString(value))
12315
+ value = { method: value };
12316
+ if (devContextOverride || getDevContext())
12317
+ globalLog.push(value);
12318
+ }
12319
+ function getGlobalLog(purge) {
12320
+ const globalLogCopy = globalLog.slice();
12321
+ return globalLogCopy;
12322
+ }
12323
+ function printGlobalLog(purge) {
12324
+ const globalLogCopy = getGlobalLog();
12325
+ const modifiedText = globalLogCopy.map((line) => {
12326
+ const { color, keyColors, method, newline } = line;
12327
+ const methodColor = Object.keys(logColors).includes(color) ? logColors[color] : logColors.cyan;
12328
+ const bodyKeys = Object.keys(line).filter((key) => !['color', 'keyColors', 'method', 'newline'].includes(key));
12329
+ const body = bodyKeys
12330
+ .map((key) => {
12331
+ const keyColor = keyColors && Object.keys(keyColors).includes(key) && logColors[keyColors[key]]
12332
+ ? logColors[keyColors[key]]
12333
+ : logColors.brightwhite;
12334
+ return `${logColors.white}${key}: ${keyColor}${line[key]}`;
12335
+ })
12336
+ .join(', ');
12337
+ const tabs = method?.length < 15 ? `\t\t` : '\t';
12338
+ return [newline ? '\n' : '', methodColor, method, tabs, logColors.white, body, logColors.reset, '\n'].join('');
12339
+ });
12340
+ if (modifiedText?.length)
12341
+ console.log(...modifiedText);
12342
+ }
12343
+ function purgeGlobalLog() {
12344
+ globalLog.length = 0;
12345
+ }
12346
+
12347
+ function isExit(matchUpStatus) {
12348
+ return [DEFAULTED, WALKOVER$2].includes(matchUpStatus);
12349
+ }
12350
+
12351
+ function assignDrawPositionBye({ provisionalPositioning, isPositionAction, tournamentRecord, drawDefinition, drawPosition, loserMatchUp, matchUpsMap, structureId, structure, event, }) {
12241
12352
  if (!drawDefinition)
12242
12353
  return { error: MISSING_DRAW_DEFINITION };
12243
12354
  if (!structure)
@@ -12247,6 +12358,7 @@ function assignDrawPositionBye({ provisionalPositioning, isPositionAction, tourn
12247
12358
  if (!structureId)
12248
12359
  ({ structureId } = structure);
12249
12360
  const stack = 'assignDrawPositionBye';
12361
+ pushGlobalLog({ method: stack, color: 'cyan', drawPosition });
12250
12362
  if (!matchUpsMap) {
12251
12363
  matchUpsMap = getMatchUpsMap({ drawDefinition });
12252
12364
  }
@@ -12259,8 +12371,9 @@ function assignDrawPositionBye({ provisionalPositioning, isPositionAction, tourn
12259
12371
  if (currentAssignment?.bye) {
12260
12372
  return { ...SUCCESS };
12261
12373
  }
12374
+ const hasPropagatedStatus = !!(loserMatchUp && matchUpsMap.drawMatchUps.find((m) => m.loserMatchUpId === loserMatchUp?.matchUpId && isExit(m.matchUpStatus)));
12262
12375
  const drawPositionIsActive = activeDrawPositions?.includes(drawPosition);
12263
- if (drawPositionIsActive) {
12376
+ if (drawPositionIsActive && !hasPropagatedStatus) {
12264
12377
  return { error: DRAW_POSITION_ACTIVE };
12265
12378
  }
12266
12379
  const positionAssignment = positionAssignments?.find((assignment) => assignment.drawPosition === drawPosition);
@@ -12269,7 +12382,7 @@ function assignDrawPositionBye({ provisionalPositioning, isPositionAction, tourn
12269
12382
  const { filled, containsBye, assignedParticipantId } = drawPositionFilled(positionAssignment);
12270
12383
  if (containsBye)
12271
12384
  return { ...SUCCESS };
12272
- if (filled && !containsBye) {
12385
+ if (filled && !containsBye && !hasPropagatedStatus) {
12273
12386
  return decorateResult({ result: { error: DRAW_POSITION_ASSIGNED }, stack });
12274
12387
  }
12275
12388
  const appliedPolicies = getAppliedPolicies({
@@ -12293,6 +12406,9 @@ function assignDrawPositionBye({ provisionalPositioning, isPositionAction, tourn
12293
12406
  positionAssignments?.forEach((assignment) => {
12294
12407
  if (assignment.drawPosition === drawPosition) {
12295
12408
  assignment.bye = true;
12409
+ if (hasPropagatedStatus) {
12410
+ assignment.participantId = undefined;
12411
+ }
12296
12412
  }
12297
12413
  });
12298
12414
  if (structure.structureType === CONTAINER) {
@@ -12406,6 +12522,8 @@ function assignRoundRobinBYE({ tournamentRecord, drawDefinition, drawPosition, m
12406
12522
  });
12407
12523
  }
12408
12524
  function advanceDrawPosition({ drawPositionToAdvance, inContextDrawMatchUps, sourceDrawPositions, tournamentRecord, drawDefinition, matchUpsMap, matchUpId, event, }) {
12525
+ const stack = 'advanceDrawPosition';
12526
+ pushGlobalLog({ method: stack, color: 'cyan', drawPositionToAdvance });
12409
12527
  const matchUp = matchUpsMap.drawMatchUps.find((matchUp) => matchUp.matchUpId === matchUpId);
12410
12528
  const inContextMatchUp = inContextDrawMatchUps.find((matchUp) => matchUp.matchUpId === matchUpId);
12411
12529
  const structureId = inContextMatchUp?.structureId;
@@ -12518,6 +12636,14 @@ function advanceWinner({ drawPositionToAdvance, inContextDrawMatchUps, sourceDra
12518
12636
  winningSide: undefined,
12519
12637
  drawPositions,
12520
12638
  });
12639
+ const changedDrawPosition = noContextWinnerMatchUp.drawPositions.find((position) => !twoDrawPositions.includes(position));
12640
+ pushGlobalLog({
12641
+ method: stack,
12642
+ color: 'brightyellow',
12643
+ changedDrawPosition,
12644
+ pairedDrawPositionIsBye,
12645
+ drawPositionIsBye,
12646
+ });
12521
12647
  modifyMatchUpNotice({
12522
12648
  tournamentId: tournamentRecord?.tournamentId,
12523
12649
  matchUp: noContextWinnerMatchUp,
@@ -12572,6 +12698,8 @@ function advanceWinner({ drawPositionToAdvance, inContextDrawMatchUps, sourceDra
12572
12698
  }
12573
12699
  function assignFedDrawPositionBye({ loserTargetDrawPosition, tournamentRecord, loserTargetLink, drawDefinition, loserMatchUp, matchUpsMap, event, }) {
12574
12700
  const { roundNumber } = loserMatchUp;
12701
+ const stack = 'assignFedDrawPositionBye';
12702
+ pushGlobalLog({ method: stack, color: 'cyan', loserTargetDrawPosition });
12575
12703
  const mappedMatchUps = matchUpsMap?.mappedMatchUps || {};
12576
12704
  const loserStructureMatchUps = mappedMatchUps[loserMatchUp.structureId].matchUps;
12577
12705
  const { initialRoundNumber } = getInitialRoundNumber({
@@ -12615,65 +12743,6 @@ function modifyRoundRobinMatchUpsStatus({ positionAssignments, tournamentRecord,
12615
12743
  });
12616
12744
  }
12617
12745
 
12618
- const logColors = {
12619
- reset: '\x1b[0m',
12620
- bright: '\x1b[1m',
12621
- dim: '\x1b[2m',
12622
- red: '\x1b[31m',
12623
- brightred: '\x1b[91m',
12624
- green: '\x1b[32m',
12625
- brightgreen: '\x1b[92m',
12626
- yellow: '\x1b[33m',
12627
- brightyellow: '\x1b[93m',
12628
- blue: '\x1b[34m',
12629
- brightblue: '\x1b[94m',
12630
- pinkbackground: '\x1b[105m',
12631
- magenta: '\x1b[35m',
12632
- brightmagenta: '\x1b[95m',
12633
- cyan: '\x1b[36m',
12634
- brightcyan: '\x1b[96m',
12635
- white: '\x1b[37m',
12636
- brightwhite: '\x1b[97m',
12637
- };
12638
-
12639
- const globalLog = [];
12640
- function pushGlobalLog(value, devContextOverride) {
12641
- if (isString(value))
12642
- value = { method: value };
12643
- if (devContextOverride || getDevContext())
12644
- globalLog.push(value);
12645
- }
12646
- function getGlobalLog(purge) {
12647
- const globalLogCopy = globalLog.slice();
12648
- return globalLogCopy;
12649
- }
12650
- function printGlobalLog(purge) {
12651
- const globalLogCopy = getGlobalLog();
12652
- const modifiedText = globalLogCopy.map((line) => {
12653
- const { color, keyColors, method, newline } = line;
12654
- const methodColor = Object.keys(logColors).includes(color) ? logColors[color] : logColors.cyan;
12655
- const bodyKeys = Object.keys(line).filter((key) => !['color', 'keyColors', 'method', 'newline'].includes(key));
12656
- const body = bodyKeys
12657
- .map((key) => {
12658
- const keyColor = (line[key] === undefined && logColors.red) ||
12659
- (keyColors &&
12660
- Object.keys(keyColors).includes(key) &&
12661
- logColors[keyColors[key]] &&
12662
- logColors[keyColors[key]]) ||
12663
- logColors.brightwhite;
12664
- return `${logColors.white}${key}: ${keyColor}${line[key]}`;
12665
- })
12666
- .join(', ');
12667
- const tabs = (method?.length <= 12 && '\t\t\t') || (method?.length <= 20 && `\t\t`) || '\t';
12668
- return [newline ? '\n' : '', methodColor, method, tabs, logColors.white, body, logColors.reset, '\n'].join('');
12669
- });
12670
- if (modifiedText?.length)
12671
- console.log(...modifiedText);
12672
- }
12673
- function purgeGlobalLog() {
12674
- globalLog.length = 0;
12675
- }
12676
-
12677
12746
  function clearDrawPosition(params) {
12678
12747
  let { inContextDrawMatchUps, participantId, drawPosition } = params;
12679
12748
  const { tournamentRecord, drawDefinition, structureId, matchUpsMap, event } = params;
@@ -12904,12 +12973,10 @@ function removeDrawPosition$1({ inContextDrawMatchUps, positionAssignments, tour
12904
12973
  const matchUpAssignments = positionAssignments.filter(({ drawPosition }) => targetMatchUp.drawPositions?.includes(drawPosition));
12905
12974
  const matchUpContainsBye = matchUpAssignments.filter((assignment) => assignment.bye).length;
12906
12975
  const newMatchUpStatus = (matchUpContainsBye && BYE) ||
12907
- (targetMatchUp.matchUpStatus &&
12908
- [DEFAULTED, WALKOVER$2].includes(targetMatchUp.matchUpStatus) &&
12909
- targetMatchUp.matcHUpStatus) ||
12976
+ (targetMatchUp.matchUpStatus && isExit(targetMatchUp.matchUpStatus) && targetMatchUp.matcHUpStatus) ||
12910
12977
  TO_BE_PLAYED;
12911
12978
  targetMatchUp.matchUpStatus = newMatchUpStatus;
12912
- if (targetMatchUp.matchUpStatus && [WALKOVER$2, DEFAULTED].includes(targetMatchUp.matchUpStatus))
12979
+ if (targetMatchUp.matchUpStatus && isExit(targetMatchUp.matchUpStatus))
12913
12980
  targetMatchUp.winningSide = undefined;
12914
12981
  const removedDrawPosition = initialDrawPositions?.find((position) => !targetMatchUp.drawPositions?.includes(position));
12915
12982
  const noChange = initialDrawPositions?.includes(drawPosition) &&
@@ -14189,7 +14256,7 @@ function getParticipantEntries(params) {
14189
14256
  const scheduledMinutes = timeStringMinutes$1(scheduledTime);
14190
14257
  for (const consideredItem of scheduleItemsToConsider) {
14191
14258
  const ignoreItem = consideredItem.matchUpId === scheduleItem.matchUpId ||
14192
- ([WALKOVER$2, DEFAULTED].includes(consideredItem.matchUpStatus) && !consideredItem.checkScoreHasValue);
14259
+ (isExit(consideredItem.matchUpStatus) && !consideredItem.checkScoreHasValue);
14193
14260
  if (ignoreItem)
14194
14261
  continue;
14195
14262
  const typeChange = scheduleItem.matchUpType !== consideredItem.matchUpType;
@@ -14974,21 +15041,32 @@ function addEventEntries(params) {
14974
15041
  if (validSingles &&
14975
15042
  (!event.gender ||
14976
15043
  !genderEnforced ||
14977
- [MIXED, ANY].includes(event.gender) ||
14978
- event.gender === participant.person?.sex)) {
15044
+ isMixed(event.gender) ||
15045
+ isAny(event.gender) ||
15046
+ coercedGender(event.gender) === coercedGender(participant.person?.sex))) {
14979
15047
  return true;
14980
15048
  }
14981
15049
  if (validDoubles && !isUngrouped(entryStatus)) {
14982
15050
  return true;
14983
15051
  }
14984
15052
  if (event.eventType === DOUBLES$1 && participant.participantType === INDIVIDUAL && isUngrouped(entryStatus)) {
15053
+ if (event.gender &&
15054
+ genderEnforced &&
15055
+ !(isMixed(event.gender) || isAny(event.gender)) &&
15056
+ coercedGender(event.gender) !== coercedGender(participant.person?.sex)) {
15057
+ mismatchedGender.push({
15058
+ participantId: participant.participantId,
15059
+ sex: participant.person?.sex,
15060
+ });
15061
+ return false;
15062
+ }
14985
15063
  return true;
14986
15064
  }
14987
15065
  if (validSingles &&
14988
15066
  event.gender &&
14989
15067
  genderEnforced &&
14990
- ![MIXED, ANY].includes(event.gender) &&
14991
- event.gender !== participant.person?.sex) {
15068
+ !(isMixed(event.gender) || isAny(event.gender)) &&
15069
+ coercedGender(event.gender) !== coercedGender(participant.person?.sex)) {
14992
15070
  mismatchedGender.push({
14993
15071
  participantId: participant.participantId,
14994
15072
  sex: participant.person?.sex,
@@ -16627,9 +16705,7 @@ function assignMatchUpDrawPosition({ inContextDrawMatchUps, sourceMatchUpStatus,
16627
16705
  });
16628
16706
  const matchUpAssignments = positionAssignments?.filter((assignment) => updatedDrawPositions.includes(assignment.drawPosition));
16629
16707
  const isByeMatchUp = matchUpAssignments?.find(({ bye }) => bye);
16630
- const isDoubleExitExit = matchUp?.matchUpStatus &&
16631
- [WALKOVER$2, DEFAULTED].includes(matchUp.matchUpStatus) &&
16632
- updatedDrawPositions.filter(Boolean).length < 2;
16708
+ const isDoubleExitExit = matchUp?.matchUpStatus && isExit(matchUp.matchUpStatus) && updatedDrawPositions.filter(Boolean).length < 2;
16633
16709
  matchUpStatus =
16634
16710
  (isByeMatchUp && BYE) ||
16635
16711
  matchUpStatus ||
@@ -16638,7 +16714,7 @@ function assignMatchUpDrawPosition({ inContextDrawMatchUps, sourceMatchUpStatus,
16638
16714
  [DOUBLE_WALKOVER, DOUBLE_DEFAULT].includes(matchUp.matchUpStatus) &&
16639
16715
  matchUp.matchUpStatus) ||
16640
16716
  TO_BE_PLAYED;
16641
- const isWalkover = !!([WALKOVER$2, DEFAULTED].includes(matchUp?.matchUpStatus) && matchUp?.winningSide);
16717
+ const isPropagatedExit = !!(isExit(matchUp?.matchUpStatus) && matchUp?.winningSide);
16642
16718
  if (matchUp && positionAdded) {
16643
16719
  inContextDrawMatchUps =
16644
16720
  getAllDrawMatchUps({
@@ -16652,7 +16728,7 @@ function assignMatchUpDrawPosition({ inContextDrawMatchUps, sourceMatchUpStatus,
16652
16728
  drawPosition,
16653
16729
  matchUpId,
16654
16730
  }))
16655
- || (isWalkover && matchUp.winningSide)
16731
+ || (isPropagatedExit && matchUp.winningSide)
16656
16732
  || undefined;
16657
16733
  if (matchUp?.matchUpStatusCodes) {
16658
16734
  updateMatchUpStatusCodes({
@@ -16666,7 +16742,7 @@ function assignMatchUpDrawPosition({ inContextDrawMatchUps, sourceMatchUpStatus,
16666
16742
  Object.assign(matchUp, {
16667
16743
  drawPositions: updatedDrawPositions,
16668
16744
  winningSide: exitWinningSide,
16669
- matchUpStatus: isWalkover ? matchUp?.matchUpStatus : matchUpStatus,
16745
+ matchUpStatus: isPropagatedExit ? matchUp?.matchUpStatus : matchUpStatus,
16670
16746
  });
16671
16747
  modifyMatchUpNotice({
16672
16748
  tournamentId: tournamentRecord?.tournamentId,
@@ -16709,7 +16785,7 @@ function assignMatchUpDrawPosition({ inContextDrawMatchUps, sourceMatchUpStatus,
16709
16785
  }
16710
16786
  }
16711
16787
  }
16712
- else if (positionAssigned && isWalkover) {
16788
+ else if (positionAssigned && isPropagatedExit) {
16713
16789
  if (winnerMatchUp) {
16714
16790
  const result = assignMatchUpDrawPosition({
16715
16791
  matchUpId: winnerMatchUp.matchUpId,
@@ -23200,7 +23276,7 @@ function modifyMatchUpScore(params) {
23200
23276
  }
23201
23277
 
23202
23278
  function attemptToModifyScore(params) {
23203
- const { matchUpStatusCodes, matchUpStatus, structure, matchUp, dualMatchUp, inContextMatchUp, autoCalcDisabled, propagateExitStatus, } = params;
23279
+ const { propagateExitStatus, matchUpStatusCodes, autoCalcDisabled, inContextMatchUp, matchUpStatus, dualMatchUp, structure, matchUp, } = params;
23204
23280
  const matchUpStatusIsValid = isDirectingMatchUpStatus({ matchUpStatus }) ||
23205
23281
  ([CANCELLED$1, ABANDONED$1].includes(matchUpStatus) && dualMatchUp) ||
23206
23282
  autoCalcDisabled;
@@ -23211,7 +23287,7 @@ function attemptToModifyScore(params) {
23211
23287
  const validToScore = hasAdHocSides ||
23212
23288
  drawPositionsAssignedParticipantIds({ structure, matchUp, inContextMatchUp }) ||
23213
23289
  params.appliedPolicies?.[POLICY_TYPE_SCORING]?.requireParticipantsForScoring === false ||
23214
- ([WALKOVER$2, DEFAULTED].includes(matchUpStatus) && participantsCount === 1 && propagateExitStatus);
23290
+ (isExit(matchUpStatus) && participantsCount === 1 && propagateExitStatus);
23215
23291
  if (!validToScore)
23216
23292
  return decorateResult({ result: { error: MISSING_ASSIGNMENTS }, stack });
23217
23293
  const removeScore = [WALKOVER$2].includes(matchUpStatus);
@@ -23935,7 +24011,7 @@ function directLoser(params) {
23935
24011
  }
23936
24012
  }
23937
24013
  }
23938
- return { ...SUCCESS, stack, context };
24014
+ return decorateResult({ result: { ...SUCCESS }, stack, context });
23939
24015
  function loserLinkFedFMLC() {
23940
24016
  const stack = 'loserLinkFedFMLC';
23941
24017
  if (validForConsolation) {
@@ -25632,7 +25708,7 @@ function getValidModifyAssignedPairAction({ tournamentParticipants, returnPartic
25632
25708
  }
25633
25709
 
25634
25710
  function isActiveDownstream(params) {
25635
- const { inContextDrawMatchUps, targetData, drawDefinition, relevantLink, matchUpStatus, score, winningSide } = params;
25711
+ const { inContextDrawMatchUps, targetData, drawDefinition, relevantLink } = params;
25636
25712
  const fmlcBYE = relevantLink?.linkCondition === FIRST_MATCHUP && targetData?.matchUp?.matchUpStatus === BYE;
25637
25713
  if (fmlcBYE)
25638
25714
  return false;
@@ -25646,20 +25722,16 @@ function isActiveDownstream(params) {
25646
25722
  const loserExitPropagation = loserTargetData?.targetMatchUps?.loserMatchUp;
25647
25723
  const loserIndex = loserTargetData?.targetMatchUps?.loserMatchUpDrawPositionIndex;
25648
25724
  const propagatedLoserParticipant = loserExitPropagation?.sides[loserIndex]?.participant;
25649
- const loserMatchUpExit = [DEFAULTED, WALKOVER$2].includes(loserMatchUp?.matchUpStatus) && !propagatedLoserParticipant;
25725
+ const isLoserMatchUpWO = isExit(loserMatchUp?.matchUpStatus);
25726
+ const loserMatchUpExit = isLoserMatchUpWO && !propagatedLoserParticipant;
25650
25727
  const loserMatchUpParticipantsCount = loserMatchUp?.sides?.reduce((acc, current) => (current?.participant ? ++acc : acc), 0) ?? 0;
25651
- const isLoserMatchUpAPropagatedExitStatus = loserMatchUp?.winningSide &&
25652
- [DEFAULTED, WALKOVER$2].includes(loserMatchUp?.matchUpStatus) &&
25653
- propagatedLoserParticipant &&
25654
- loserMatchUpParticipantsCount === 1;
25655
- const isClearScore = matchUpStatus === TO_BE_PLAYED && score?.scoreStringSide1 === '' && score?.scoreStringSide2 === '' && !winningSide;
25728
+ const isLoserMatchUpWalkoverWithOnePlayer = loserMatchUp?.winningSide && isLoserMatchUpWO && loserMatchUpParticipantsCount === 1;
25656
25729
  const winnerDrawPositionsCount = winnerMatchUp?.drawPositions?.filter(Boolean).length || 0;
25657
- if ((isLoserMatchUpAPropagatedExitStatus && isClearScore) ||
25658
- (!isLoserMatchUpAPropagatedExitStatus &&
25659
- ((loserMatchUp?.winningSide && !loserMatchUpExit) ||
25660
- (winnerMatchUp?.winningSide &&
25661
- winnerDrawPositionsCount === 2 &&
25662
- (!winnerMatchUp.feedRound || ![WALKOVER$2, DEFAULTED].includes(winnerMatchUp?.matchUpStatus)))))) {
25730
+ if (!isLoserMatchUpWalkoverWithOnePlayer &&
25731
+ ((loserMatchUp?.winningSide && !loserMatchUpExit) ||
25732
+ (winnerMatchUp?.winningSide &&
25733
+ winnerDrawPositionsCount === 2 &&
25734
+ (!winnerMatchUp.feedRound || !isExit(winnerMatchUp?.matchUpStatus))))) {
25663
25735
  return true;
25664
25736
  }
25665
25737
  const winnerTargetData = winnerMatchUp &&
@@ -25803,7 +25875,7 @@ const matchUpActionConstants = {
25803
25875
  function collectionMatchUpActions({ specifiedPolicyDefinitions, inContextDrawMatchUps, matchUpParticipantIds, matchUpActionsPolicy, inContextMatchUp, policyActions, enforceGender, participantId, sideNumber, matchUpId, matchUp, drawId, side, }) {
25804
25876
  const validActions = [];
25805
25877
  const firstFoundSide = inContextMatchUp.sides?.find((side) => side.participant);
25806
- const assignedGender = inContextMatchUp.gender === MIXED &&
25878
+ const assignedGender = isMixed(inContextMatchUp.gender) &&
25807
25879
  inContextMatchUp.sideNumber &&
25808
25880
  inContextMatchUp.sides?.filter((side) => side.particiapntId).length === 1 &&
25809
25881
  firstFoundSide?.participant?.person?.sex;
@@ -25822,9 +25894,9 @@ function collectionMatchUpActions({ specifiedPolicyDefinitions, inContextDrawMat
25822
25894
  const inContextDualMatchUp = inContextDrawMatchUps?.find((drawMatchUp) => drawMatchUp.matchUpId === inContextMatchUp.matchUpTieId);
25823
25895
  const availableIndividualParticipants = inContextDualMatchUp?.sides?.map((side) => side?.participant?.individualParticipants?.filter(({ participantId, person }) => !existingParticipantIds?.includes(participantId) &&
25824
25896
  (!gender ||
25825
- gender === ANY ||
25897
+ isAny(gender) ||
25826
25898
  person.sex === gender ||
25827
- (gender === MIXED && !assignedGender) ||
25899
+ (isMixed(gender) && !assignedGender) ||
25828
25900
  (assignedGender && person.sex !== assignedGender))));
25829
25901
  const availableParticipants = sideNumber
25830
25902
  ? availableIndividualParticipants?.[sideNumber - 1]
@@ -27219,15 +27291,16 @@ function getValidGender(params) {
27219
27291
  [];
27220
27292
  const validPairGender = !eventGender ||
27221
27293
  !pairGender?.length ||
27222
- ANY === eventGender ||
27223
- ([MALE, FEMALE].includes(eventGender) && pairGender[0] === eventGender) ||
27224
- (MIXED === eventGender &&
27294
+ isAny(eventGender) ||
27295
+ (isGendered(eventGender) && coercedGender(pairGender[0]) === coercedGender(eventGender)) ||
27296
+ (isMixed(eventGender) &&
27225
27297
  ((pairGender.length === 1 && participant.individualParticipantIds?.length === 1) || pairGender.length === 2));
27226
27298
  const personGender = participant?.person?.sex;
27227
27299
  const validPersonGender = !participant?.person ||
27228
27300
  !eventGender ||
27229
- [ANY, MIXED].includes(eventGender) ||
27230
- ([MALE, FEMALE].includes(eventGender) && personGender === eventGender);
27301
+ isMixed(eventGender) ||
27302
+ isAny(eventGender) ||
27303
+ (isGendered(eventGender) && coercedGender(personGender) === coercedGender(eventGender));
27231
27304
  return !genderEnforced || (validPairGender && validPersonGender);
27232
27305
  }
27233
27306
 
@@ -39055,16 +39128,16 @@ function addEventEntryPairs(params) {
39055
39128
  const invalidParticipantIdPairs = participantIdPairs.filter((pair) => {
39056
39129
  if (pair.length !== 2)
39057
39130
  return true;
39058
- if (!event.gender || event.gender === ANY)
39131
+ if (!event.gender || isAny(event.gender))
39059
39132
  return false;
39060
39133
  if (!genderMap.has(pair[0]) || !genderMap.has(pair[1]))
39061
39134
  return true;
39062
39135
  const participantGenders = pair.map((id) => genderMap.get(id));
39063
- let invalidParticiapntGenders = (event.gender === MALE && (participantGenders[0] !== MALE || participantGenders[1] !== MALE)) ||
39064
- (event.gender === FEMALE && (participantGenders[0] !== FEMALE || participantGenders[1] !== FEMALE));
39065
- if (event.gender === MIXED) {
39136
+ let invalidParticiapntGenders = (isMale(event.gender) && (!isMale(participantGenders[0]) || !isMale(participantGenders[1]))) ||
39137
+ (isFemale(event.gender) && (!isFemale(participantGenders[0]) || !isFemale(participantGenders[1])));
39138
+ if (isMixed(event.gender)) {
39066
39139
  participantGenders.sort(stringSort);
39067
- if (participantGenders[0] !== FEMALE || participantGenders[1] !== MALE)
39140
+ if (!isFemale(participantGenders[0]) || !isMale(participantGenders[1]))
39068
39141
  invalidParticiapntGenders = true;
39069
39142
  }
39070
39143
  return invalidParticiapntGenders;
@@ -39426,8 +39499,10 @@ function generateEventsFromTieFormat(params) {
39426
39499
  for (const participant of params.tournamentRecord.participants ?? []) {
39427
39500
  if (individualParticipantIds?.includes(participant.participantId)) {
39428
39501
  const gender = participant.person?.sex;
39429
- if (gender && [MALE, FEMALE].includes(gender)) {
39430
- genderedParticipants[gender].push(participant.participantId);
39502
+ if (gender && isGendered(gender)) {
39503
+ const coerced = coercedGender(gender);
39504
+ if (coerced)
39505
+ genderedParticipants[coerced].push(participant.participantId);
39431
39506
  }
39432
39507
  }
39433
39508
  }
@@ -39447,9 +39522,9 @@ function generateEventsFromTieFormat(params) {
39447
39522
  };
39448
39523
  if (params.addEntriesFromTeams) {
39449
39524
  const entryStatus = eventType === DOUBLES_EVENT ? UNGROUPED : params.entryStatus || DIRECT_ACCEPTANCE;
39450
- const participantIds = eventGender === MIXED
39525
+ const participantIds = isMixed(eventGender)
39451
39526
  ? [...genderedParticipants[MALE], ...genderedParticipants[FEMALE]]
39452
- : (genderedParticipants[eventGender] ?? []);
39527
+ : (genderedParticipants[coercedGender(eventGender) || OTHER$3] ?? []);
39453
39528
  if (participantIds.length) {
39454
39529
  const result = addEventEntries({
39455
39530
  participantIds,
@@ -40916,9 +40991,9 @@ function getParticipantsProfile({ enteredParticipants }) {
40916
40991
  function checkGenderUpdates({ noFlightsNoDraws, enteredParticipantGenders, eventUpdates, stack }) {
40917
40992
  const validGender = !enteredParticipantGenders.length ||
40918
40993
  !eventUpdates.gender ||
40919
- eventUpdates.gender === ANY ||
40994
+ isAny(eventUpdates.gender) ||
40920
40995
  (enteredParticipantGenders.length === 1 && enteredParticipantGenders[0] === eventUpdates.gender) ||
40921
- (noFlightsNoDraws && eventUpdates.gender === MIXED);
40996
+ (noFlightsNoDraws && isMixed(eventUpdates.gender));
40922
40997
  return eventUpdates.gender && !validGender
40923
40998
  ? decorateResult({
40924
40999
  context: { gender: eventUpdates.gender, validGender },
@@ -41440,7 +41515,8 @@ function generateLineUps(params) {
41440
41515
  const participantIds = [];
41441
41516
  generateRange(0, singlesMatchUp ? 1 : 2).forEach((i) => {
41442
41517
  const nextParticipantId = typeSort?.find((participant) => {
41443
- const targetGender = gender && (([MALE, FEMALE].includes(gender) && gender) || (gender === MIXED && [MALE, FEMALE][i]));
41518
+ const coerced = coercedGender(gender);
41519
+ const targetGender = coerced && ((isGendered(gender) && coerced) || (isMixed(gender) && [MALE, FEMALE][i]));
41444
41520
  return ((!targetGender || targetGender === participant.person?.sex) &&
41445
41521
  !collectionParticipantIds.includes(participant.participantId));
41446
41522
  })?.participantId;
@@ -42243,8 +42319,8 @@ function replaceTieMatchUpParticipantId(params) {
42243
42319
  const newParticipant = targetParticipants.find(({ participantId }) => participantId === newParticipantId);
42244
42320
  const genderEnforced = (params.enforceGender ?? matchUpActionsPolicy?.participants?.enforceGender) !== false;
42245
42321
  if (genderEnforced &&
42246
- [MALE, FEMALE].includes(inContextTieMatchUp?.gender) &&
42247
- inContextTieMatchUp?.gender !== newParticipant?.person?.sex) {
42322
+ isGendered(inContextTieMatchUp?.gender) &&
42323
+ coercedGender(inContextTieMatchUp?.gender) !== coercedGender(newParticipant?.person?.sex)) {
42248
42324
  return { error: INVALID_PARTICIPANT, info: 'Gender mismatch' };
42249
42325
  }
42250
42326
  const substitutionProcessCodes = matchUpActionsPolicy?.processCodes?.substitution;
@@ -42704,8 +42780,8 @@ function assignTieMatchUpParticipantId(params) {
42704
42780
  POLICY_MATCHUP_ACTIONS_DEFAULT[POLICY_TYPE_MATCHUP_ACTIONS];
42705
42781
  const genderEnforced = (params.enforceGender ?? matchUpActionsPolicy?.participants?.enforceGender) !== false;
42706
42782
  if (genderEnforced &&
42707
- [MALE, FEMALE].includes(inContextTieMatchUp?.gender) &&
42708
- inContextTieMatchUp?.gender !== participantToAssign.person?.sex) {
42783
+ isGendered(inContextTieMatchUp?.gender) &&
42784
+ coercedGender(inContextTieMatchUp?.gender) !== coercedGender(participantToAssign.person?.sex)) {
42709
42785
  return { error: INVALID_PARTICIPANT, info: 'Gender mismatch' };
42710
42786
  }
42711
42787
  const { individualParticipantIds, participantType } = participantToAssign;
@@ -43186,10 +43262,8 @@ function removeDrawPosition({ inContextDrawMatchUps, positionAssignments, source
43186
43262
  const matchUpAssignments = positionAssignments.filter(({ drawPosition }) => matchUp.drawPositions?.includes(drawPosition));
43187
43263
  const matchUpContainsBye = matchUpAssignments.filter((assignment) => assignment.bye).length;
43188
43264
  matchUp.matchUpStatus =
43189
- (matchUpContainsBye && BYE) ||
43190
- ([DEFAULTED, WALKOVER$2].includes(matchUp.matchUpStatus) && matchUp.matchUpStatus) ||
43191
- TO_BE_PLAYED;
43192
- if ([WALKOVER$2, DEFAULTED].includes(matchUp.matchUpStatus))
43265
+ (matchUpContainsBye && BYE) || (isExit(matchUp.matchUpStatus) && matchUp.matchUpStatus) || TO_BE_PLAYED;
43266
+ if (isExit(matchUp.matchUpStatus))
43193
43267
  matchUp.winningSide = undefined;
43194
43268
  if (matchUp.matchUpStatusCodes) {
43195
43269
  updateMatchUpStatusCodes({
@@ -43402,6 +43476,10 @@ function removeDirectedLoser({ sourceMatchUpStatus, loserParticipantId, tourname
43402
43476
  delete assignment.participantId;
43403
43477
  }
43404
43478
  });
43479
+ if (sourceMatchUpId && sourceMatchUpStatus) {
43480
+ const targetMatchUp = matchUpsMap?.drawMatchUps?.find(({ matchUpId }) => matchUpId === loserMatchUp.matchUpId);
43481
+ targetMatchUp.matchUpStatusCodes = sourceMatchUpStatus === DOUBLE_WALKOVER ? ['WO', 'WO'] : [];
43482
+ }
43405
43483
  structure.seedAssignments = (structure.seedAssignments ?? []).filter((assignment) => assignment.participantId !== loserParticipantId);
43406
43484
  if (dualMatchUp) {
43407
43485
  const drawPositionSideIndex = loserMatchUp?.sides.reduce((sideIndex, side, i) => (side.drawPosition === relevantDrawPosition ? i : sideIndex), undefined);
@@ -43423,6 +43501,11 @@ function removeDirectedLoser({ sourceMatchUpStatus, loserParticipantId, tourname
43423
43501
  function removeDirectedBye({ inContextDrawMatchUps, tournamentRecord, drawDefinition, drawPosition, matchUpsMap, targetLink, event, }) {
43424
43502
  const structureId = targetLink.target.structureId;
43425
43503
  const stack = 'removeDirectedBye';
43504
+ pushGlobalLog({
43505
+ color: 'brightyellow',
43506
+ method: stack,
43507
+ drawPosition,
43508
+ });
43426
43509
  const result = clearDrawPosition({
43427
43510
  inContextDrawMatchUps,
43428
43511
  tournamentRecord,
@@ -43488,8 +43571,9 @@ function doubleExitAdvancement(params) {
43488
43571
  return decorateResult({ result: { ...SUCCESS }, stack });
43489
43572
  const { matchUp: sourceMatchUp, targetMatchUps, targetLinks } = targetData;
43490
43573
  const { loserMatchUp, winnerMatchUp, loserTargetDrawPosition } = targetMatchUps;
43491
- const loserMatchUpIsEmptyExit = [WALKOVER$2, DEFAULTED].includes(loserMatchUp?.matchUpStatus) &&
43574
+ const loserMatchUpIsEmptyExit = isExit(loserMatchUp?.matchUpStatus) &&
43492
43575
  !loserMatchUp.sides?.map((side) => side.participantId ?? side.participant).filter(Boolean).length;
43576
+ const loserMatchUpIsDoubleExit = loserMatchUp?.matchUpStatus === DOUBLE_WALKOVER;
43493
43577
  if (loserMatchUp && loserMatchUp.matchUpStatus !== BYE) {
43494
43578
  const { loserTargetLink } = targetLinks;
43495
43579
  if (appliedPolicies?.progression?.doubleExitPropagateBye ||
@@ -43499,15 +43583,17 @@ function doubleExitAdvancement(params) {
43499
43583
  tournamentRecord,
43500
43584
  loserTargetLink,
43501
43585
  drawDefinition,
43586
+ loserMatchUp,
43502
43587
  matchUpsMap,
43503
43588
  event,
43504
43589
  });
43505
43590
  if (result.error)
43506
43591
  return decorateResult({ result, stack });
43507
43592
  }
43508
- else if (!loserMatchUpIsEmptyExit) {
43593
+ else if (!loserMatchUpIsDoubleExit) {
43509
43594
  const { feedRound, drawPositions, matchUpId } = loserMatchUp;
43510
- const walkoverWinningSide = feedRound ? 2 : 2 - drawPositions.indexOf(loserTargetDrawPosition);
43595
+ let walkoverWinningSide = feedRound ? 2 : 2 - drawPositions.indexOf(loserTargetDrawPosition);
43596
+ walkoverWinningSide = loserMatchUpIsEmptyExit ? loserMatchUp.winningSide : walkoverWinningSide;
43511
43597
  const result = conditionallyAdvanceDrawPosition({
43512
43598
  ...params,
43513
43599
  targetMatchUp: loserMatchUp,
@@ -43562,6 +43648,7 @@ function conditionallyAdvanceDrawPosition(params) {
43562
43648
  const { loserTargetLink } = targetLinks;
43563
43649
  const result = advanceByeToLoserMatchUp({
43564
43650
  loserTargetDrawPosition: nextLoserTargetDrawPosition,
43651
+ loserMatchUp: nextLoserMatchUp,
43565
43652
  tournamentRecord,
43566
43653
  loserTargetLink,
43567
43654
  drawDefinition,
@@ -43580,7 +43667,7 @@ function conditionallyAdvanceDrawPosition(params) {
43580
43667
  inContextDrawMatchUps,
43581
43668
  })) ||
43582
43669
  undefined;
43583
- const existingExit = [WALKOVER$2, DEFAULTED].includes(noContextTargetMatchUp.matchUpStatus) && !drawPositions.length;
43670
+ const existingExit = isExit(noContextTargetMatchUp.matchUpStatus) && !drawPositions.length;
43584
43671
  const isFinal = noContextTargetMatchUp.finishingRound === 1;
43585
43672
  const matchUpStatus = existingExit && !isFinal ? DOUBLE_EXIT : EXIT;
43586
43673
  const inContextPairedPreviousMatchUp = inContextDrawMatchUps.find((candidate) => candidate.matchUpId === pairedPreviousMatchUp.matchUpId);
@@ -43698,7 +43785,7 @@ function conditionallyAdvanceDrawPosition(params) {
43698
43785
  matchUpsMap,
43699
43786
  });
43700
43787
  }
43701
- else if ([WALKOVER$2, DEFAULTED].includes(nextWinnerMatchUp.matchUpStatus)) {
43788
+ else if (isExit(nextWinnerMatchUp.matchUpStatus)) {
43702
43789
  const result = doubleExitAdvancement({
43703
43790
  ...params,
43704
43791
  matchUpId: noContextNextWinnerMatchUp.matchUpId,
@@ -43731,7 +43818,7 @@ function conditionallyAdvanceDrawPosition(params) {
43731
43818
  walkoverWinningSide,
43732
43819
  });
43733
43820
  }
43734
- const matchUpStatus = [WALKOVER$2, DEFAULTED].includes(noContextNextWinnerMatchUp.matchUpStatus) ? EXIT : DOUBLE_EXIT;
43821
+ const matchUpStatus = isExit(noContextNextWinnerMatchUp.matchUpStatus) ? EXIT : DOUBLE_EXIT;
43735
43822
  const result = modifyMatchUpScore({
43736
43823
  matchUpId: noContextNextWinnerMatchUp.matchUpId,
43737
43824
  appliedPolicies: params.appliedPolicies,
@@ -43757,7 +43844,7 @@ function conditionallyAdvanceDrawPosition(params) {
43757
43844
  return decorateResult({ result: { ...SUCCESS }, stack });
43758
43845
  }
43759
43846
  function advanceByeToLoserMatchUp(params) {
43760
- const { loserTargetDrawPosition, tournamentRecord, loserTargetLink, drawDefinition, matchUpsMap, event } = params;
43847
+ const { loserTargetDrawPosition, tournamentRecord, loserTargetLink, drawDefinition, matchUpsMap, event, loserMatchUp, } = params;
43761
43848
  const structureId = loserTargetLink?.target?.structureId;
43762
43849
  const { structure } = findStructure({ drawDefinition, structureId });
43763
43850
  if (!structure)
@@ -43768,6 +43855,7 @@ function advanceByeToLoserMatchUp(params) {
43768
43855
  drawDefinition,
43769
43856
  structureId,
43770
43857
  matchUpsMap,
43858
+ loserMatchUp,
43771
43859
  event,
43772
43860
  });
43773
43861
  }
@@ -44071,13 +44159,36 @@ function attemptToSetWinningSide(params) {
44071
44159
  });
44072
44160
  }
44073
44161
 
44162
+ const keyColors = {
44163
+ drawPositionToRemove: 'green',
44164
+ iteration: 'brightred',
44165
+ winner: 'green',
44166
+ loser: 'brightred',
44167
+ };
44074
44168
  function removeDoubleExit(params) {
44075
44169
  const { inContextDrawMatchUps, appliedPolicies, drawDefinition, matchUpsMap, targetData, matchUp } = params;
44170
+ const { matchUpId } = matchUp;
44076
44171
  let { iteration = 0 } = params;
44077
44172
  iteration += 1;
44078
44173
  const stack = 'removeDoubleExit';
44174
+ pushGlobalLog({
44175
+ color: 'brightyellow',
44176
+ method: stack,
44177
+ matchUpId,
44178
+ iteration,
44179
+ keyColors,
44180
+ });
44079
44181
  const { targetMatchUps: { loserMatchUp, winnerMatchUp, loserTargetDrawPosition }, targetLinks: { loserTargetLink }, } = targetData;
44080
44182
  if (winnerMatchUp && winnerMatchUp.matchUpStatus !== BYE) {
44183
+ const { stage, roundNumber, roundPosition, structureName } = winnerMatchUp;
44184
+ pushGlobalLog({
44185
+ winner: 'winner',
44186
+ roundPosition,
44187
+ structureName,
44188
+ roundNumber,
44189
+ keyColors,
44190
+ stage,
44191
+ });
44081
44192
  conditionallyRemoveDrawPosition({
44082
44193
  ...params,
44083
44194
  targetMatchUp: winnerMatchUp,
@@ -44105,6 +44216,16 @@ function removeDoubleExit(params) {
44105
44216
  drawDefinition,
44106
44217
  structureId: inContextLoserMatchUp.structureId,
44107
44218
  });
44219
+ const { stage, roundNumber, roundPosition, feedRound, structureName } = loserMatchUp;
44220
+ pushGlobalLog({
44221
+ loser: 'loser',
44222
+ roundPosition,
44223
+ structureName,
44224
+ roundNumber,
44225
+ keyColors,
44226
+ feedRound,
44227
+ stage,
44228
+ });
44108
44229
  if (appliedPolicies?.progression?.doubleExitPropagateBye || byePropagatedToLoserMatchUp) {
44109
44230
  removeDirectedBye({
44110
44231
  drawPosition: loserTargetDrawPosition,
@@ -44130,6 +44251,7 @@ function removeDoubleExit(params) {
44130
44251
  function conditionallyRemoveDrawPosition(params) {
44131
44252
  const { inContextDrawMatchUps, appliedPolicies, drawDefinition, sourceMatchUp, targetMatchUp, matchUpsMap, structure, iteration, } = params;
44132
44253
  const stack = 'conditionallyRemoveDrawPosition';
44254
+ pushGlobalLog({ method: stack, structureName: structure?.structureName, iteration });
44133
44255
  const nextTargetData = positionTargets({
44134
44256
  matchUpId: targetMatchUp.matchUpId,
44135
44257
  inContextDrawMatchUps,
@@ -44169,6 +44291,17 @@ function conditionallyRemoveDrawPosition(params) {
44169
44291
  }
44170
44292
  }
44171
44293
  if (nextWinnerMatchUp && drawPositionToRemove) {
44294
+ const { stage, roundNumber, roundPosition, structureName } = nextWinnerMatchUp;
44295
+ pushGlobalLog({
44296
+ method: 'removeDirectedWinner',
44297
+ drawPositionToRemove,
44298
+ color: 'brightgreen',
44299
+ roundPosition,
44300
+ structureName,
44301
+ roundNumber,
44302
+ keyColors,
44303
+ stage,
44304
+ });
44172
44305
  removeDirectedWinner({
44173
44306
  winningDrawPosition: drawPositionToRemove,
44174
44307
  winnerMatchUp: nextWinnerMatchUp,
@@ -44325,7 +44458,7 @@ function noDownstreamDependencies(params) {
44325
44458
  }
44326
44459
  const triggerDualWinningSide = [CANCELLED$1, ABANDONED$1].includes(matchUpStatus) && params.dualWinningSideChange;
44327
44460
  const statusNotToBePlayed = matchUpStatus && matchUpStatus !== TO_BE_PLAYED;
44328
- const propagateExitStatus = params.propagateExitStatus && [WALKOVER$2, DEFAULTED].includes(matchUpStatus);
44461
+ const propagateExitStatus = params.propagateExitStatus && isExit(matchUpStatus);
44329
44462
  const result = ((winningSide || triggerDualWinningSide || propagateExitStatus) && attemptToSetWinningSide(params)) ||
44330
44463
  (scoreWithNoWinningSide && removeDirected(removeScore)) ||
44331
44464
  (statusNotToBePlayed && attemptToSetMatchUpStatus(params)) ||
@@ -45072,6 +45205,15 @@ function addMatchUpResumeTime({ removePriorValues, tournamentRecord, drawDefinit
45072
45205
  }
45073
45206
  }
45074
45207
 
45208
+ function hasPropagatedExitDownstream(params) {
45209
+ const { targetData, matchUpsMap } = params;
45210
+ const { targetMatchUps: { loserMatchUp }, } = targetData;
45211
+ const isLoserMatchUpWO = isExit(loserMatchUp?.matchUpStatus);
45212
+ const hasLoserMatchUpUpstreamWOMatches = !!matchUpsMap?.drawMatchUps.find((m) => m.loserMatchUpId === loserMatchUp?.matchUpId && isExit(m.matchUpStatus));
45213
+ return ((hasLoserMatchUpUpstreamWOMatches && loserMatchUp?.matchUpStatus === DOUBLE_WALKOVER) ||
45214
+ (hasLoserMatchUpUpstreamWOMatches && isLoserMatchUpWO));
45215
+ }
45216
+
45075
45217
  function getProjectedDualWinningSide({ drawDefinition, matchUpStatus, matchUpsMap, winningSide, dualMatchUp, tieFormat, structure, matchUp, event, score, }) {
45076
45218
  const projectedDualMatchUp = makeDeepCopy(dualMatchUp, undefined, true);
45077
45219
  for (const tieMatchUp of projectedDualMatchUp?.tieMatchUps || []) {
@@ -45155,7 +45297,7 @@ function swapWinnerLoser(params) {
45155
45297
  }
45156
45298
 
45157
45299
  function setMatchUpState(params) {
45158
- const stack = 'setMatchUpState';
45300
+ const stack = 'setMatchUpStatus';
45159
45301
  if (params.matchUpStatus && [WALKOVER$2, DOUBLE_WALKOVER].includes(params.matchUpStatus))
45160
45302
  params.score = undefined;
45161
45303
  const { allowChangePropagation, disableScoreValidation, propagateExitStatus, tournamentRecords, tournamentRecord, disableAutoCalc, enableAutoCalc, drawDefinition, matchUpStatus, winningSide, matchUpId, event, score, } = params;
@@ -45209,6 +45351,13 @@ function setMatchUpState(params) {
45209
45351
  structure,
45210
45352
  matchUp,
45211
45353
  });
45354
+ const isClearScore = matchUpStatus === TO_BE_PLAYED && score?.scoreStringSide1 === '' && score?.scoreStringSide2 === '' && !winningSide;
45355
+ const propagatedExitDownStream = hasPropagatedExitDownstream(params);
45356
+ if (propagatedExitDownStream && isClearScore) {
45357
+ return {
45358
+ error: PROPAGATED_EXITS_DOWNSTREAM,
45359
+ };
45360
+ }
45212
45361
  const activeDownstream = isActiveDownstream(params);
45213
45362
  let dualWinningSideChange;
45214
45363
  if (isTeam) {
@@ -45401,6 +45550,12 @@ function setMatchUpState(params) {
45401
45550
  return swapWinnerLoser(params);
45402
45551
  }
45403
45552
  const matchUpWinner = (winningSide && !matchUpTieId) || params.projectedWinningSide;
45553
+ pushGlobalLog({
45554
+ activeDownstream,
45555
+ matchUpWinner,
45556
+ method: stack,
45557
+ winningSide,
45558
+ });
45404
45559
  const result = (!activeDownstream && noDownstreamDependencies(params)) ||
45405
45560
  (matchUpWinner && winningSideWithDownstreamDependencies(params)) ||
45406
45561
  ((directingMatchUpStatus || params.autoCalcDisabled) && applyMatchUpValues(params)) || {
@@ -45481,7 +45636,7 @@ function checkParticipants({ assignedDrawPositions, propagateExitStatus, inConte
45481
45636
  if (matchUpStatus && particicipantsRequiredMatchUpStatuses.includes(matchUpStatus) && !requiredParticipants) {
45482
45637
  return decorateResult({
45483
45638
  info: 'matchUpStatus requires assigned participants',
45484
- context: { matchUpStatus, requiredParticipants, propagateExitStatus: propagateExitStatus, participantsCount },
45639
+ context: { matchUpStatus, requiredParticipants },
45485
45640
  result: { error: INVALID_MATCHUP_STATUS },
45486
45641
  });
45487
45642
  }
@@ -45785,7 +45940,13 @@ function matchUpScore(params) {
45785
45940
 
45786
45941
  function progressExitStatus({ sourceMatchUpStatusCodes, propagateExitStatus, sourceMatchUpStatus, loserParticipantId, tournamentRecord, drawDefinition, loserMatchUp, matchUpsMap, event, }) {
45787
45942
  const stack = 'progressExitStatus';
45788
- const carryOverMatchUpStatus = ([WALKOVER$2, DEFAULTED].includes(sourceMatchUpStatus) && sourceMatchUpStatus) || WALKOVER$2;
45943
+ pushGlobalLog({
45944
+ matchUpId: loserMatchUp?.matchUpId,
45945
+ matchUpStatus: sourceMatchUpStatus,
45946
+ color: 'magenta',
45947
+ method: stack,
45948
+ });
45949
+ const carryOverMatchUpStatus = (isExit(sourceMatchUpStatus) && sourceMatchUpStatus) || WALKOVER$2;
45789
45950
  const inContextMatchUps = getAllDrawMatchUps({
45790
45951
  inContext: true,
45791
45952
  drawDefinition,
@@ -45795,7 +45956,7 @@ function progressExitStatus({ sourceMatchUpStatusCodes, propagateExitStatus, sou
45795
45956
  const updatedLoserMatchUp = inContextMatchUps?.find((m) => m.matchUpId === loserMatchUp?.matchUpId);
45796
45957
  if (updatedLoserMatchUp?.matchUpId && loserMatchUpStatus) {
45797
45958
  let winningSide = undefined;
45798
- const statusCodes = updatedLoserMatchUp.matchUpStatusCodes?.map((sc) => (typeof sc === 'string' ? sc : 'WO')) ?? [];
45959
+ const statusCodes = updatedLoserMatchUp.matchUpStatusCodes?.map((sc) => (typeof sc === 'string' ? sc : OUTCOME_WALKOVER)) ?? [];
45799
45960
  const loserParticipantSide = updatedLoserMatchUp.sides?.find((s) => s.participantId === loserParticipantId);
45800
45961
  if (loserParticipantSide?.sideNumber) {
45801
45962
  const participantsCount = updatedLoserMatchUp?.sides?.reduce((count, current) => {
@@ -45806,7 +45967,7 @@ function progressExitStatus({ sourceMatchUpStatusCodes, propagateExitStatus, sou
45806
45967
  statusCodes[0] = sourceMatchUpStatusCodes[0];
45807
45968
  }
45808
45969
  else {
45809
- if (![WALKOVER$2, DEFAULTED].includes(loserMatchUp.matchUpStatus)) {
45970
+ if (!isExit(loserMatchUp.matchUpStatus)) {
45810
45971
  winningSide = loserParticipantSide.sideNumber === 1 ? 2 : 1;
45811
45972
  statusCodes[0] = sourceMatchUpStatusCodes[0];
45812
45973
  }
@@ -45852,7 +46013,7 @@ function setMatchUpStatus(params) {
45852
46013
  tournamentRecord,
45853
46014
  });
45854
46015
  if (result.error)
45855
- return decorateResult({ stack, result });
46016
+ return result;
45856
46017
  if (result.drawDefinition)
45857
46018
  params.drawDefinition = result.drawDefinition;
45858
46019
  params.event = result.event;
@@ -45869,7 +46030,7 @@ function setMatchUpStatus(params) {
45869
46030
  undefined;
45870
46031
  const { outcome, setTBlast } = params;
45871
46032
  if (outcome?.winningSide && ![1, 2].includes(outcome.winningSide)) {
45872
- return decorateResult({ result: { error: INVALID_WINNING_SIDE }, stack });
46033
+ return { error: INVALID_WINNING_SIDE };
45873
46034
  }
45874
46035
  if (matchUpFormat) {
45875
46036
  const result = setMatchUpMatchUpFormat({
@@ -45880,7 +46041,7 @@ function setMatchUpStatus(params) {
45880
46041
  event,
45881
46042
  });
45882
46043
  if (result.error)
45883
- return decorateResult({ stack, result });
46044
+ return result;
45884
46045
  }
45885
46046
  if (outcome?.score?.sets && !outcome.score.scoreStringSide1) {
45886
46047
  const { score: scoreObject } = matchUpScore({ ...outcome, setTBlast });
@@ -48924,7 +49085,7 @@ var namesData$1 = {
48924
49085
 
48925
49086
  function generatePersonData(params) {
48926
49087
  const { count = 100, sex } = params || {};
48927
- if (!count || (sex && ![MALE, FEMALE].includes(sex)))
49088
+ if (!count || (sex && !isGendered(sex)))
48928
49089
  return { personData: [], error: INVALID_VALUES };
48929
49090
  const buffer = Math.ceil(count * 1.3);
48930
49091
  const { lastNames, firstFemale, firstMale } = namesData$1;
@@ -48966,8 +49127,8 @@ function generatePersons(params) {
48966
49127
  const { personExtensions, consideredDate, isMock = true, gendersCount, personData, category, sex } = params || {};
48967
49128
  if (isNaN(count))
48968
49129
  return { error: INVALID_VALUES };
48969
- const maleCount = gendersCount?.[MALE] || (sex === MALE && count) || 0;
48970
- const femaleCount = gendersCount?.[FEMALE] || (sex === FEMALE && count) || 0;
49130
+ const maleCount = gendersCount?.[MALE] || (isMale(sex) && count) || 0;
49131
+ const femaleCount = gendersCount?.[FEMALE] || (isFemale(sex) && count) || 0;
48971
49132
  count = Math.max(count, maleCount + femaleCount);
48972
49133
  const defaultCount = count - (maleCount + femaleCount);
48973
49134
  const defaultMalePersonData = (maleCount &&
@@ -49450,12 +49611,13 @@ function processTieFormat(params) {
49450
49611
  const tieFormat = isObject(params.tieFormat) ? params.tieFormat : tieFormatDefaults({ namedFormat: tieFormatName });
49451
49612
  tieFormat?.collectionDefinitions?.filter(Boolean).forEach((collectionDefinition) => {
49452
49613
  const { category, collectionId, matchUpType, matchUpCount, gender } = collectionDefinition;
49453
- if ([MALE, FEMALE].includes(gender)) {
49614
+ if (isGendered(gender)) {
49615
+ const coerced = coercedGender(gender);
49454
49616
  const required = matchUpCount * (matchUpType === DOUBLES$1 ? 2 : 1);
49455
- if (genders[gender] < required)
49456
- genders[gender] = required;
49617
+ if (coerced && genders[coerced] < required)
49618
+ genders[coerced] = required;
49457
49619
  }
49458
- else if (gender === MIXED) {
49620
+ else if (isMixed(gender)) {
49459
49621
  if (genders[MALE] < matchUpCount)
49460
49622
  genders[MALE] = matchUpCount;
49461
49623
  if (genders[FEMALE] < matchUpCount)
@@ -49728,7 +49890,7 @@ function generateOutcome(params) {
49728
49890
  COMPLETED$1,
49729
49891
  ])[1];
49730
49892
  const noScore = { sets: [], scoreStringSide1: '', side2ScoreString: '' };
49731
- if ([WALKOVER$2, DEFAULTED].includes(matchUpStatus)) {
49893
+ if (isExit(matchUpStatus)) {
49732
49894
  winningSide = winningSide || randomInt(1, 2);
49733
49895
  const outcome = {
49734
49896
  score: noScore,
@@ -50254,7 +50416,7 @@ function generateEventParticipants(params) {
50254
50416
  const participantsCount = eventProfile.drawProfiles?.length
50255
50417
  ? mainParticipantsCount + qualifyingParticipantsCount
50256
50418
  : (eventProfile.participantsProfile?.participantsCount ?? 0);
50257
- const sex = [MALE, FEMALE].includes(gender) ? gender : undefined;
50419
+ const sex = isGendered(gender) ? gender : undefined;
50258
50420
  const idPrefix = participantsProfile?.idPrefix ? `E-${eventIndex}-${participantsProfile?.idPrefix}` : undefined;
50259
50421
  const { participants: uniqueFlightParticipants } = generateParticipants({
50260
50422
  uuids: eventProfile.uuids || uuids,
@@ -50653,8 +50815,9 @@ function generateEventWithDraw(params) {
50653
50815
  drawSize,
50654
50816
  }));
50655
50817
  Object.keys(genders).forEach((key) => {
50656
- if ([MALE, FEMALE].includes(key) && genders[key]) {
50657
- gendersCount[key] = drawSize * genders[key];
50818
+ const coerced = coercedGender(key);
50819
+ if (coerced && isGendered(key) && genders[coerced]) {
50820
+ gendersCount[coerced] = drawSize * genders[coerced];
50658
50821
  }
50659
50822
  });
50660
50823
  individualParticipantCount = teamSize * ((drawSize || 0) + qualifyingParticipantsCount);
@@ -50695,7 +50858,7 @@ function generateEventWithDraw(params) {
50695
50858
  : [];
50696
50859
  const femaleIndividualParticipantIds = genders[FEMALE]
50697
50860
  ? unique
50698
- .filter(({ participantType, person }) => participantType === INDIVIDUAL && person?.sex === FEMALE)
50861
+ .filter(({ participantType, person }) => participantType === INDIVIDUAL && isFemale(person?.sex))
50699
50862
  .map(getParticipantId)
50700
50863
  : [];
50701
50864
  const remainingParticipantIds = unique
@@ -51729,8 +51892,9 @@ function anonymizeTournamentRecord({ keepExtensions = [], anonymizeParticipantNa
51729
51892
  const individualParticipants = (tournamentRecord.participants || []).filter(({ participantType }) => participantType === INDIVIDUAL);
51730
51893
  const gendersCount = individualParticipants.reduce((counts, participant) => {
51731
51894
  const gender = participant.person?.sex;
51732
- if ([MALE, FEMALE].includes(gender)) {
51733
- counts[gender] += 1;
51895
+ const coerced = coercedGender(gender);
51896
+ if (coerced && isGendered(gender)) {
51897
+ counts[coerced] += 1;
51734
51898
  }
51735
51899
  else {
51736
51900
  counts[OTHER$3] += 1;