tods-competition-factory 2.1.13 → 2.1.14

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.1.13';
6
+ return '2.1.14';
7
7
  }
8
8
 
9
9
  const SINGLES_MATCHUP = 'SINGLES';
@@ -9414,46 +9414,6 @@ function scheduledMatchUpDate({ timeStamp, schedule, matchUp }) {
9414
9414
  : schedule;
9415
9415
  }
9416
9416
 
9417
- function matchUpAllocatedCourts({ timeStamp, schedule, matchUp }) {
9418
- const { itemValue: allocatedCourts, timeStamp: itemTimeStamp } = latestVisibleTimeItemValue({
9419
- timeItems: matchUp?.timeItems || [],
9420
- itemType: ALLOCATE_COURTS,
9421
- });
9422
- return !schedule || (itemTimeStamp && timeStamp && new Date(itemTimeStamp).getTime() > new Date(timeStamp).getTime())
9423
- ? { allocatedCourts: makeDeepCopy(allocatedCourts, false, true) }
9424
- : schedule;
9425
- }
9426
-
9427
- function matchUpAssignedCourtId({ timeStamp, schedule, matchUp }) {
9428
- const { itemValue: courtId, timeStamp: itemTimeStamp } = latestVisibleTimeItemValue({
9429
- timeItems: matchUp?.timeItems || [],
9430
- itemType: ASSIGN_COURT,
9431
- });
9432
- return !schedule || (itemTimeStamp && timeStamp && new Date(itemTimeStamp).getTime() > new Date(timeStamp).getTime())
9433
- ? { courtId }
9434
- : schedule;
9435
- }
9436
-
9437
- function matchUpAssignedVenueId({ timeStamp, schedule, matchUp }) {
9438
- const { itemValue: venueId, timeStamp: itemTimeStamp } = latestVisibleTimeItemValue({
9439
- timeItems: matchUp?.timeItems || [],
9440
- itemType: ASSIGN_VENUE,
9441
- });
9442
- return !schedule || (itemTimeStamp && timeStamp && new Date(itemTimeStamp).getTime() > new Date(timeStamp).getTime())
9443
- ? { venueId }
9444
- : schedule;
9445
- }
9446
-
9447
- function matchUpTimeModifiers({ timeStamp, schedule, matchUp }) {
9448
- const { itemValue: timeModifiers, timeStamp: itemTimeStamp } = latestVisibleTimeItemValue({
9449
- timeItems: matchUp?.timeItems || [],
9450
- itemType: TIME_MODIFIERS,
9451
- });
9452
- return !schedule || (itemTimeStamp && timeStamp && new Date(itemTimeStamp).getTime() > new Date(timeStamp).getTime())
9453
- ? { timeModifiers }
9454
- : schedule;
9455
- }
9456
-
9457
9417
  function timeDate$1(value) {
9458
9418
  if (validTimeString.test(value)) {
9459
9419
  const dateString = getUTCdateString();
@@ -9523,30 +9483,6 @@ function msToTime(s) {
9523
9483
  return pad((s / 3.6e6) | 0) + ':' + pad(((s % 3.6e6) / 6e4) | 0) + ':' + pad(((s % 6e4) / 1000) | 0);
9524
9484
  }
9525
9485
 
9526
- function matchUpCourtOrder({ timeStamp, schedule, matchUp }) {
9527
- const { itemValue: courtOrder, timeStamp: itemTimeStamp } = latestVisibleTimeItemValue({
9528
- timeItems: matchUp?.timeItems || [],
9529
- itemType: COURT_ORDER,
9530
- });
9531
- return !schedule || (itemTimeStamp && timeStamp && new Date(itemTimeStamp).getTime() > new Date(timeStamp).getTime())
9532
- ? { courtOrder }
9533
- : schedule;
9534
- }
9535
-
9536
- function getHomeParticipantId(params) {
9537
- const { timeStamp, schedule, matchUp } = params;
9538
- const paramsCheck = checkRequiredParameters(params, [{ [MATCHUP]: true }]);
9539
- if (paramsCheck.error)
9540
- return paramsCheck;
9541
- const { itemValue: homeParticipantId, timeStamp: itemTimeStamp } = latestVisibleTimeItemValue({
9542
- timeItems: matchUp?.timeItems || [],
9543
- itemType: HOME_PARTICIPANT_ID,
9544
- });
9545
- return !schedule || (itemTimeStamp && timeStamp && new Date(itemTimeStamp).getTime() > new Date(timeStamp).getTime())
9546
- ? { homeParticipantId }
9547
- : schedule;
9548
- }
9549
-
9550
9486
  function matchUpStartTime({ matchUp }) {
9551
9487
  const timeItems = matchUp?.timeItems || [];
9552
9488
  const getTimeStamp = (item) => (!item.createdAt ? 0 : new Date(item.createdAt).getTime());
@@ -9879,15 +9815,21 @@ function getMatchUpScheduleDetails(params) {
9879
9815
  let schedule;
9880
9816
  const { eventIds, drawIds } = scheduleVisibilityFilters ?? {};
9881
9817
  if ((!eventIds || eventIds.includes(matchUp.eventId)) && (!drawIds || drawIds.includes(matchUp.drawId))) {
9882
- const scheduleSource = { matchUp };
9883
- const { allocatedCourts } = matchUpAllocatedCourts(scheduleSource);
9884
- const { homeParticipantId } = getHomeParticipantId(scheduleSource);
9885
- const { scheduledTime } = scheduledMatchUpTime(scheduleSource);
9886
- const { timeModifiers } = matchUpTimeModifiers(scheduleSource);
9887
- let { scheduledDate } = scheduledMatchUpDate(scheduleSource);
9888
- const { venueId } = matchUpAssignedVenueId(scheduleSource);
9889
- const { courtId } = matchUpAssignedCourtId(scheduleSource);
9890
- const { courtOrder } = matchUpCourtOrder(scheduleSource);
9818
+ const getTimeStamp = (item) => (!item.createdAt ? 0 : new Date(item.createdAt).getTime());
9819
+ const timeItemMap = new Map();
9820
+ const sortedTimeItems = matchUp.timeItems?.toSorted((a, b) => getTimeStamp(a) - getTimeStamp(b)) ?? [];
9821
+ for (const timeItem of sortedTimeItems) {
9822
+ timeItemMap.set(timeItem.itemType, timeItem.itemValue);
9823
+ }
9824
+ const homeParticipantId = timeItemMap.get(HOME_PARTICIPANT_ID);
9825
+ const allocatedCourts = timeItemMap.get(ALLOCATE_COURTS);
9826
+ const scheduledTime = timeItemMap.get(SCHEDULED_TIME);
9827
+ const timeModifiers = timeItemMap.get(TIME_MODIFIERS);
9828
+ let scheduledDate = timeItemMap.get(SCHEDULED_DATE);
9829
+ const official = timeItemMap.get(ASSIGN_OFFICIAL);
9830
+ const courtOrder = timeItemMap.get(COURT_ORDER);
9831
+ const venueId = timeItemMap.get(ASSIGN_VENUE);
9832
+ const courtId = timeItemMap.get(ASSIGN_COURT);
9891
9833
  let timeAfterRecovery, averageMinutes, recoveryMinutes, typeChangeRecoveryMinutes, typeChangeTimeAfterRecovery;
9892
9834
  const eventType = matchUp.matchUpType ?? matchUpType;
9893
9835
  if (scheduleTiming && scheduledTime && afterRecoveryTimes && eventType) {
@@ -9944,15 +9886,16 @@ function getMatchUpScheduleDetails(params) {
9944
9886
  scheduledDate,
9945
9887
  scheduledTime,
9946
9888
  isoDateString,
9947
- allocatedCourts,
9948
9889
  homeParticipantId,
9949
- timeModifiers,
9950
9890
  venueAbbreviation,
9891
+ allocatedCourts,
9892
+ timeModifiers,
9951
9893
  venueName,
9952
9894
  venueId,
9953
9895
  courtOrder,
9954
9896
  courtName,
9955
9897
  courtId,
9898
+ official,
9956
9899
  typeChangeRecoveryMinutes,
9957
9900
  recoveryMinutes,
9958
9901
  averageMinutes,
@@ -10549,6 +10492,36 @@ function addMatchUpContext({ scheduleVisibilityFilters, sourceDrawPositionRanges
10549
10492
  return matchUpWithContext;
10550
10493
  }
10551
10494
 
10495
+ function matchUpAllocatedCourts({ timeStamp, schedule, matchUp }) {
10496
+ const { itemValue: allocatedCourts, timeStamp: itemTimeStamp } = latestVisibleTimeItemValue({
10497
+ timeItems: matchUp?.timeItems || [],
10498
+ itemType: ALLOCATE_COURTS,
10499
+ });
10500
+ return !schedule || (itemTimeStamp && timeStamp && new Date(itemTimeStamp).getTime() > new Date(timeStamp).getTime())
10501
+ ? { allocatedCourts: makeDeepCopy(allocatedCourts, false, true) }
10502
+ : schedule;
10503
+ }
10504
+
10505
+ function matchUpAssignedCourtId({ timeStamp, schedule, matchUp }) {
10506
+ const { itemValue: courtId, timeStamp: itemTimeStamp } = latestVisibleTimeItemValue({
10507
+ timeItems: matchUp?.timeItems || [],
10508
+ itemType: ASSIGN_COURT,
10509
+ });
10510
+ return !schedule || (itemTimeStamp && timeStamp && new Date(itemTimeStamp).getTime() > new Date(timeStamp).getTime())
10511
+ ? { courtId }
10512
+ : schedule;
10513
+ }
10514
+
10515
+ function matchUpAssignedVenueId({ timeStamp, schedule, matchUp }) {
10516
+ const { itemValue: venueId, timeStamp: itemTimeStamp } = latestVisibleTimeItemValue({
10517
+ timeItems: matchUp?.timeItems || [],
10518
+ itemType: ASSIGN_VENUE,
10519
+ });
10520
+ return !schedule || (itemTimeStamp && timeStamp && new Date(itemTimeStamp).getTime() > new Date(timeStamp).getTime())
10521
+ ? { venueId }
10522
+ : schedule;
10523
+ }
10524
+
10552
10525
  function filterMatchUps(params) {
10553
10526
  if (!Array.isArray(params.matchUps))
10554
10527
  return [];
@@ -12251,10 +12224,13 @@ function pushGlobalLog(value, devContextOverride) {
12251
12224
  }
12252
12225
  function getGlobalLog(purge) {
12253
12226
  const globalLogCopy = globalLog.slice();
12227
+ if (purge) {
12228
+ globalLog.length = 0;
12229
+ }
12254
12230
  return globalLogCopy;
12255
12231
  }
12256
12232
  function printGlobalLog(purge) {
12257
- const globalLogCopy = getGlobalLog();
12233
+ const globalLogCopy = getGlobalLog(purge);
12258
12234
  const modifiedText = globalLogCopy.map((line) => {
12259
12235
  const { color, keyColors, method, newline } = line;
12260
12236
  const methodColor = Object.keys(logColors).includes(color) ? logColors[color] : logColors.cyan;
@@ -13774,7 +13750,7 @@ function processSides(params) {
13774
13750
  }
13775
13751
 
13776
13752
  function getParticipantEntries(params) {
13777
- const { participantFilters, convertExtensions, policyDefinitions, tournamentRecord, usePublishState, contextProfile, participantMap, withPotentialMatchUps, withRankingProfile, withScheduleItems, scheduleAnalysis, withTeamMatchUps, withStatistics, withOpponents, withMatchUps, withSeeding, withEvents, withDraws, } = params;
13753
+ const { participantFilters, convertExtensions, policyDefinitions, tournamentRecord, usePublishState, participantMap, contextProfile, withPotentialMatchUps, withRankingProfile, withScheduleItems, scheduleAnalysis, withTeamMatchUps, withStatistics, withOpponents, withMatchUps, withSeeding, withEvents, withDraws, } = params;
13778
13754
  const targetParticipantIds = participantFilters?.participantIds;
13779
13755
  const getRelevantParticipantIds = (participantId) => {
13780
13756
  const relevantParticipantIds = [participantId];
@@ -13888,10 +13864,8 @@ function getParticipantEntries(params) {
13888
13864
  const assignedParticipantIds = structures
13889
13865
  .filter(({ stage, stageSequence }) => (stage === MAIN && stageSequence === 1) || stage === QUALIFYING)
13890
13866
  .flatMap((structure) => {
13867
+ const { positionAssignments } = getPositionAssignments$1({ structure });
13891
13868
  const { seedAssignments, stageSequence, stage } = structure;
13892
- const { positionAssignments } = getPositionAssignments$1({
13893
- structure,
13894
- });
13895
13869
  if (stage === MAIN) {
13896
13870
  drawSize = positionAssignments?.length ?? 0;
13897
13871
  mainPositionAssignments = positionAssignments;
@@ -19134,9 +19108,7 @@ function automatedPositioning(params) {
19134
19108
  }
19135
19109
 
19136
19110
  function automatedPlayoffPositioning(params) {
19137
- const { applyPositioning = true, provisionalPositioning, tournamentRecord, drawDefinition, seedingProfile, structureId, placeByes, seedsOnly, event, } = params;
19138
- if (!event)
19139
- return { error: EVENT_NOT_FOUND };
19111
+ const { applyPositioning = true, provisionalPositioning, tournamentRecord, drawDefinition, seedingProfile, structureId, placeByes, seedsOnly, } = params;
19140
19112
  if (!drawDefinition)
19141
19113
  return { error: DRAW_DEFINITION_NOT_FOUND };
19142
19114
  const structureIsComplete = isCompletedStructure({
@@ -20880,7 +20852,7 @@ function availablePlayoffProfiles({ playoffPositions, drawDefinition, structure,
20880
20852
  function getPositionRangeMap({ playoffGroups, drawDefinition, structureId }) {
20881
20853
  if (!drawDefinition)
20882
20854
  return { error: MISSING_DRAW_DEFINITION };
20883
- if (typeof structureId !== 'string' || !Array.isArray(playoffGroups)) {
20855
+ if (!isString(structureId) || !Array.isArray(playoffGroups)) {
20884
20856
  return { error: INVALID_VALUES };
20885
20857
  }
20886
20858
  const playoffGroupFinishingPostions = playoffGroups.map(({ finishingPositions }) => finishingPositions).flat();
@@ -21491,7 +21463,7 @@ function generateAndPopulateRRplayoffStructures(params) {
21491
21463
  });
21492
21464
  }
21493
21465
  const { sourceStructureId, requireSequential, tournamentRecord, drawDefinition, playoffGroups, groupCount, groupSize, event, } = params;
21494
- const { structures: playoffStructures = [], links: playoffLinks = [], finishingPositionTargets, positionRangeMap, error, } = processPlayoffGroups({
21466
+ const processResult = processPlayoffGroups({
21495
21467
  requireSequential,
21496
21468
  sourceStructureId,
21497
21469
  playoffGroups,
@@ -21499,8 +21471,9 @@ function generateAndPopulateRRplayoffStructures(params) {
21499
21471
  groupSize,
21500
21472
  ...params,
21501
21473
  });
21502
- if (error)
21503
- return { error };
21474
+ if (processResult.error)
21475
+ return decorateResult({ result: processResult, stack });
21476
+ const { structures: playoffStructures = [], links: playoffLinks = [], finishingPositionTargets, positionRangeMap, } = processResult;
21504
21477
  const positionsPlayedOff = finishingPositionTargets
21505
21478
  ?.map(({ finishingPositions }) => finishingPositions)
21506
21479
  .flat()
@@ -28715,10 +28688,14 @@ function generateScoreString(params) {
28715
28688
  return `[${tiebreakScore.join('-')}]`;
28716
28689
  }
28717
28690
  const lowTiebreakScore = Math.min(t1, t2);
28691
+ const lowTiebreakSide = lowTiebreakScore === t1 ? 1 : 2;
28718
28692
  const tiebreak = lowTiebreakScore ? `(${lowTiebreakScore})` : '';
28719
28693
  const s1 = side1Score || (isNumeric(side1Score) || autoComplete ? 0 : '');
28720
28694
  const s2 = side2Score || (isNumeric(side2Score) || autoComplete ? 0 : '');
28721
- let scoreString = reverseScores ? `${[s2, s1].join('-')}${tiebreak}` : `${[s1, s2].join('-')}${tiebreak}`;
28695
+ const includeTiebreak = (sideNumber) => (lowTiebreakSide === sideNumber ? tiebreak : '');
28696
+ const ss1 = `${s1}${includeTiebreak(1)}`;
28697
+ const ss2 = `${s2}${includeTiebreak(2)}`;
28698
+ let scoreString = reverseScores ? `${[ss2, ss1].join('-')}` : `${[ss1, ss2].join('-')}`;
28722
28699
  if (['-', ' '].includes(scoreString))
28723
28700
  scoreString = '';
28724
28701
  return scoreString;
@@ -29361,13 +29338,14 @@ function getMatchUpWinner({ matchUpFormat, matchUpStatus, winningSide, sets }) {
29361
29338
  return { matchUpWinningSide };
29362
29339
  }
29363
29340
 
29364
- function checkSetIsComplete({ ignoreTiebreak = false, matchUpScoringFormat, matchUpFormat, isTiebreakSet, isDecidingSet, set, }) {
29341
+ function checkSetIsComplete({ ignoreTiebreak = false, matchUpScoringFormat, matchUpFormat, isTiebreakSet, isDecidingSet, isTimedSet, set, }) {
29365
29342
  if (!set)
29366
29343
  return { error: MISSING_VALUE, info: 'missing set' };
29367
29344
  matchUpScoringFormat = matchUpScoringFormat || (matchUpFormat && parse(matchUpFormat));
29368
29345
  const setFormat = (isDecidingSet && matchUpScoringFormat.finalSetFormat) || matchUpScoringFormat?.setFormat || {};
29369
29346
  const { side1Score, side2Score } = set;
29370
29347
  const { setTo, tiebreakAt } = setFormat;
29348
+ const hasScore = side1Score || side2Score;
29371
29349
  const leadingSide = getLeadingSide({ set });
29372
29350
  const scoreDiff = Math.abs(side1Score - side2Score);
29373
29351
  const containsSetTo = side1Score >= setTo || side2Score >= setTo;
@@ -29383,7 +29361,8 @@ function checkSetIsComplete({ ignoreTiebreak = false, matchUpScoringFormat, matc
29383
29361
  : 2;
29384
29362
  const hasWinMargin = scoreDiff >= winMargin;
29385
29363
  const validNormalSetScore = containsSetTo && (hasWinMargin || requiresTiebreak);
29386
- return !!((validNormalSetScore || isTiebreakSet) && (!requiresTiebreak || tiebreakIsValid));
29364
+ return !!(((isTimedSet && hasScore) || validNormalSetScore || isTiebreakSet) &&
29365
+ (!requiresTiebreak || tiebreakIsValid));
29387
29366
  }
29388
29367
  function getLeadingSide({ set }) {
29389
29368
  if (set.side1Score || set.side2Score) {
@@ -31919,18 +31898,17 @@ function parseScoreString({ tiebreakTo = 7, scoreString = '' }) {
31919
31898
  .filter(Boolean)
31920
31899
  .map((set, index) => parseSet({ set, setNumber: index + 1 }));
31921
31900
  function parseSet({ set, setNumber }) {
31922
- const matchTiebreak = set?.startsWith('[') &&
31923
- set
31924
- .split('[')[1]
31925
- .split(']')[0]
31926
- .split('-')
31927
- .map((sideScore) => parseInt(sideScore));
31928
- const setString = (set.includes('(') && set.split('(')[0]) || (set.includes('[') && set.split('[')[0]) || set;
31901
+ const inParentheses = /\(([^)]+)\)/;
31902
+ const inBrackets = /\[([^)]+)\]/;
31903
+ const tiebreak = inParentheses.exec(set);
31904
+ const supertiebreak = inBrackets.exec(set);
31905
+ const matchTiebreak = set?.startsWith('[') && supertiebreak && supertiebreak[1].split('-').map((sideScore) => parseInt(sideScore));
31906
+ const setString = (tiebreak && set.replace(tiebreak[0], '')) || (supertiebreak && set.replace(supertiebreak[0], '')) || set;
31929
31907
  const setScores = !matchTiebreak && setString.split('-').map((sideScore) => parseInt(sideScore));
31930
31908
  const winningSide = matchTiebreak
31931
31909
  ? (matchTiebreak[0] > matchTiebreak[1] && 1) || (matchTiebreak[0] < matchTiebreak[1] && 2) || undefined
31932
31910
  : (setScores[0] > setScores[1] && 1) || (setScores[0] < setScores[1] && 2) || undefined;
31933
- const setTiebreakLowScore = set.includes('(') ? set.split('(')[1].split(')')[0] : undefined;
31911
+ const setTiebreakLowScore = tiebreak ? tiebreak[1] : undefined;
31934
31912
  const side1TiebreakPerspective = setTiebreakLowScore &&
31935
31913
  getTiebreakComplement({
31936
31914
  lowValue: setTiebreakLowScore,
@@ -31951,7 +31929,7 @@ function parseScoreString({ tiebreakTo = 7, scoreString = '' }) {
31951
31929
  }
31952
31930
  }
31953
31931
 
31954
- function getSetWinningSide({ matchUpScoringFormat, isDecidingSet, isTiebreakSet, setObject, }) {
31932
+ function getSetWinningSide({ matchUpScoringFormat, isDecidingSet, isTiebreakSet, isTimedSet, setObject, }) {
31955
31933
  if (!setObject)
31956
31934
  return undefined;
31957
31935
  const leadingSide = getLeadingSide({ set: setObject });
@@ -31960,6 +31938,7 @@ function getSetWinningSide({ matchUpScoringFormat, isDecidingSet, isTiebreakSet,
31960
31938
  set: setObject,
31961
31939
  isDecidingSet,
31962
31940
  isTiebreakSet,
31941
+ isTimedSet,
31963
31942
  });
31964
31943
  return (setIsComplete && leadingSide) || undefined;
31965
31944
  }
@@ -31969,13 +31948,14 @@ function analyzeSet(params) {
31969
31948
  if (!setObject)
31970
31949
  return { error: MISSING_SET_OBJECT };
31971
31950
  const { setNumber } = setObject || {};
31972
- const { bestOf } = matchUpScoringFormat || {};
31973
- const isDecidingSet = !!(setNumber && bestOf && setNumber === bestOf);
31951
+ const { bestOf, exactly } = matchUpScoringFormat || {};
31952
+ const maxSetNumber = bestOf || exactly;
31953
+ const isDecidingSet = !!(setNumber && maxSetNumber && setNumber === maxSetNumber);
31974
31954
  const setFormat = (isDecidingSet && matchUpScoringFormat?.finalSetFormat) || matchUpScoringFormat?.setFormat;
31975
31955
  const expectTiebreakSet = !!setFormat?.tiebreakSet;
31976
31956
  const expectTimedSet = !!setFormat?.timed;
31977
31957
  const expectStandardSet = !expectTiebreakSet && !expectTimedSet;
31978
- const isValidSetNumber = !!(setNumber && bestOf && setNumber <= bestOf);
31958
+ const isValidSetNumber = !!(setNumber && maxSetNumber && setNumber <= maxSetNumber);
31979
31959
  const sideGameScores = [setObject?.side1Score, setObject?.side2Score];
31980
31960
  const sidePointScores = [setObject?.side1PointScore, setObject?.side2PointScore];
31981
31961
  const sideTiebreakScores = [setObject?.side1TiebreakScore, setObject?.side2TiebreakScore];
@@ -31991,26 +31971,28 @@ function analyzeSet(params) {
31991
31971
  const isTiebreakSet = !!(tiebreakScoresCount && !gameScoresCount);
31992
31972
  const isCompletedSet = !!setObject?.winningSide;
31993
31973
  const { error: standardSetError, result: isValidStandardSetOutcome } = checkValidStandardSetOutcome({
31994
- setObject,
31995
- setFormat,
31996
- sideGameScores,
31997
31974
  sideTiebreakScores,
31975
+ sideGameScores,
31976
+ setFormat,
31977
+ setObject,
31998
31978
  });
31999
31979
  const { error: tiebreakSetError, result: isValidTiebreakSetOutcome } = checkValidTiebreakSetOutcome({
31980
+ sideTiebreakScores,
32000
31981
  setObject,
32001
31982
  setFormat,
32002
- sideTiebreakScores,
32003
31983
  });
32004
31984
  const isValidSetOutcome = (expectStandardSet && !isTiebreakSet && isValidStandardSetOutcome) ||
32005
- (expectTiebreakSet && isTiebreakSet && isValidTiebreakSetOutcome);
31985
+ (expectTiebreakSet && isTiebreakSet && isValidTiebreakSetOutcome) ||
31986
+ expectTimedSet;
32006
31987
  const isValidSet = isValidSetNumber &&
32007
31988
  !(expectTiebreakSet && !isTiebreakSet) &&
32008
31989
  !(expectStandardSet && isTiebreakSet) &&
32009
31990
  (!isCompletedSet || isValidSetOutcome);
32010
31991
  const winningSide = getSetWinningSide({
31992
+ isTimedSet: expectTimedSet,
31993
+ matchUpScoringFormat,
32011
31994
  isDecidingSet,
32012
31995
  isTiebreakSet,
32013
- matchUpScoringFormat,
32014
31996
  setObject,
32015
31997
  });
32016
31998
  const analysis = {
@@ -33807,35 +33789,115 @@ function getAggregateTeamResults(params) {
33807
33789
  const paramsCheck = checkRequiredParameters(params, [{ [TOURNAMENT_RECORD]: true }]);
33808
33790
  if (paramsCheck.error)
33809
33791
  return paramsCheck;
33792
+ const bonusPoints = params.finishingPositionRangeBounsPoints || {};
33793
+ const teamBonusPointHashes = {};
33794
+ const getTeamParticipant = (participant) => {
33795
+ const individualTeams = participant?.individualParticipants?.map((i) => i.teams?.length === 1 && i.teams[0]);
33796
+ return ((participant?.teams?.length === 1 && participant?.teams?.[0]) ||
33797
+ (individualTeams?.[0].participantId === individualTeams?.[1].participantId && individualTeams?.[0]));
33798
+ };
33799
+ const { matchUps, participants } = getParticipants({
33800
+ participantFilters: { participantTypes: [INDIVIDUAL] },
33801
+ withRankingProfile: true,
33802
+ withStatistics: true,
33803
+ ...params,
33804
+ });
33805
+ for (const participant of participants ?? []) {
33806
+ if (participant.participantType === TEAM_PARTICIPANT)
33807
+ continue;
33808
+ if (participant.draws?.[0]?.drawId === 'draw-0-3') {
33809
+ console.log(participant.participantType, participant.draws[0].finishingPositionRange);
33810
+ }
33811
+ const teamParticipant = getTeamParticipant(participant);
33812
+ if (!teamParticipant)
33813
+ continue;
33814
+ for (const draw of participant?.draws ?? []) {
33815
+ const finishingPositionRange = draw?.finishingPositionRange?.join('-');
33816
+ if (finishingPositionRange && bonusPoints?.[finishingPositionRange]) {
33817
+ const teamParticipantId = teamParticipant?.participantId;
33818
+ const drawId = draw?.drawId;
33819
+ const hash = `${teamParticipantId}|${drawId}|${finishingPositionRange}`;
33820
+ teamBonusPointHashes[hash] = bonusPoints[finishingPositionRange];
33821
+ }
33822
+ }
33823
+ }
33824
+ const initializeResults = (teamName) => ({
33825
+ teamName,
33826
+ standingPoints: 0,
33827
+ pointsPlayed: 0,
33828
+ pointsPct: 0,
33829
+ points: 0,
33830
+ bonus: 0,
33831
+ diff: 0,
33832
+ loss: 0,
33833
+ win: 0,
33834
+ });
33835
+ const increment = (results, key, value) => {
33836
+ if (results[key] === undefined)
33837
+ results[key] = 0;
33838
+ results[key] += value;
33839
+ };
33840
+ const individualResults = {};
33810
33841
  const teamResults = {};
33811
- for (const matchUp of allTournamentMatchUps(params)?.matchUps ?? []) {
33842
+ for (const matchUp of matchUps ?? []) {
33812
33843
  const { sides, matchUpFormat } = matchUp;
33813
33844
  const parsedMatchUpFormat = matchUpFormat && parse(matchUpFormat);
33814
33845
  if (sides?.length === 2 &&
33815
33846
  parsedMatchUpFormat.setFormat?.timed &&
33816
33847
  (!parsedMatchUpFormat.finalSetFormat || parsedMatchUpFormat.finalSetFormat?.timed)) {
33817
33848
  for (const side of sides) {
33818
- const individualTeams = side?.participant?.individualParticipants?.map((i) => i.teams?.length === 1 && i.teams[0]);
33819
- const teamParticipant = (side?.participant?.teams?.length === 1 && side?.participant?.teams?.[0]) ||
33820
- (individualTeams?.[0].participantId === individualTeams?.[1].participantId && individualTeams?.[0]);
33849
+ const teamParticipant = getTeamParticipant(side.participant);
33821
33850
  const teamParticipantId = teamParticipant?.participantId;
33851
+ const participantId = side.participant?.participantId;
33852
+ const teamName = teamParticipant?.participantName;
33822
33853
  const sideNumber = side.sideNumber;
33854
+ const individualParticipantIds = side.participant?.individualParticipantIds || (participantId && [participantId]) || [];
33855
+ individualParticipantIds.forEach((individualParticipantId) => {
33856
+ if (individualParticipantId && !individualResults[individualParticipantId]) {
33857
+ individualResults[individualParticipantId] = initializeResults(teamName);
33858
+ }
33859
+ });
33823
33860
  if (teamParticipantId && sideNumber) {
33824
- if (!teamResults[teamParticipantId]) {
33825
- teamResults[teamParticipantId] = { score: 0, diff: 0, teamName: teamParticipant.participantName };
33861
+ if (!teamResults[teamParticipantId])
33862
+ teamResults[teamParticipantId] = initializeResults(teamName);
33863
+ const resultObjects = [
33864
+ ...individualParticipantIds.map((id) => individualResults[id]),
33865
+ teamResults[teamParticipantId],
33866
+ ];
33867
+ if (matchUp.winningSide) {
33868
+ if (sideNumber === matchUp.winningSide) {
33869
+ resultObjects.forEach((resultObject) => increment(resultObject, 'win', 1));
33870
+ }
33871
+ else {
33872
+ resultObjects.forEach((resultObject) => increment(resultObject, 'loss', 1));
33873
+ }
33826
33874
  }
33827
- for (const set of matchUp.score?.sets ?? []) {
33875
+ const sets = matchUp.score?.sets || [];
33876
+ for (const set of sets) {
33828
33877
  const opponentPoints = set?.[`side${3 - sideNumber}Score`] || 0;
33829
33878
  const points = set?.[`side${sideNumber}Score`] || 0;
33830
33879
  const diff = points - opponentPoints;
33831
- teamResults[teamParticipantId].score += points;
33832
- teamResults[teamParticipantId].diff += diff;
33880
+ resultObjects.forEach((resultObject) => increment(resultObject, 'pointsPlayed', points + opponentPoints));
33881
+ resultObjects.forEach((resultObject) => increment(resultObject, 'points', points));
33882
+ resultObjects.forEach((resultObject) => increment(resultObject, 'diff', diff));
33833
33883
  }
33834
33884
  }
33835
33885
  }
33836
33886
  }
33837
33887
  }
33838
- return { ...SUCCESS, teamResults };
33888
+ for (const hash of Object.keys(teamBonusPointHashes)) {
33889
+ const [teamParticipantId] = hash.split('|');
33890
+ if (teamResults[teamParticipantId]) {
33891
+ teamResults[teamParticipantId].bonus += teamBonusPointHashes[hash];
33892
+ teamResults[teamParticipantId].pointsPct = parseFloat((teamResults[teamParticipantId].points / teamResults[teamParticipantId].pointsPlayed).toFixed(2));
33893
+ teamResults[teamParticipantId].standingPoints =
33894
+ teamResults[teamParticipantId].win + teamResults[teamParticipantId].bonus;
33895
+ }
33896
+ }
33897
+ for (const individualParticipantId of Object.keys(individualResults)) {
33898
+ individualResults[individualParticipantId].pointsPct = parseFloat((individualResults[individualParticipantId].points / individualResults[individualParticipantId].pointsPlayed).toFixed(2));
33899
+ }
33900
+ return { ...SUCCESS, individualResults, teamResults };
33839
33901
  }
33840
33902
 
33841
33903
  function checkIsDual(tournamentRecord) {
@@ -36890,6 +36952,20 @@ function calculateWinCriteria({ collectionDefinitions = [], collectionGroups = [
36890
36952
  return { valueGoal, ...SUCCESS };
36891
36953
  }
36892
36954
 
36955
+ function getHomeParticipantId(params) {
36956
+ const { timeStamp, schedule, matchUp } = params;
36957
+ const paramsCheck = checkRequiredParameters(params, [{ [MATCHUP]: true }]);
36958
+ if (paramsCheck.error)
36959
+ return paramsCheck;
36960
+ const { itemValue: homeParticipantId, timeStamp: itemTimeStamp } = latestVisibleTimeItemValue({
36961
+ timeItems: matchUp?.timeItems || [],
36962
+ itemType: HOME_PARTICIPANT_ID,
36963
+ });
36964
+ return !schedule || (itemTimeStamp && timeStamp && new Date(itemTimeStamp).getTime() > new Date(timeStamp).getTime())
36965
+ ? { homeParticipantId }
36966
+ : schedule;
36967
+ }
36968
+
36893
36969
  function getMatchUpContextIds({ matchUps, matchUpId }) {
36894
36970
  if (!validMatchUps(matchUps))
36895
36971
  return { error: INVALID_VALUES };
@@ -37232,8 +37308,8 @@ function analyzeMatchUp(params) {
37232
37308
  const losingSideSetsCount = setsWinCounts[matchUpLosingSideIndex];
37233
37309
  const maxSetsCount = Math.max(...setsWinCounts);
37234
37310
  const maxSetsInstances = instanceCount(setsWinCounts)[maxSetsCount];
37235
- const { bestOf } = matchUpScoringFormat ?? {};
37236
- const setsToWin = (bestOf && Math.ceil(bestOf / 2)) || 1;
37311
+ const { bestOf, exactly } = matchUpScoringFormat ?? {};
37312
+ const setsToWin = (bestOf && Math.ceil(bestOf / 2)) || exactly || 1;
37237
37313
  const calculatedWinningSide = (maxSetsCount === setsToWin && maxSetsInstances === 1 && setsWinCounts.indexOf(maxSetsCount) + 1) || undefined;
37238
37314
  const validMatchUpWinningSide = winningSideSetsCount > losingSideSetsCount && matchUpWinningSide === calculatedWinningSide;
37239
37315
  const validMatchUpOutcome = calculatedWinningSide && completedSetsHaveValidOutcomes && validMatchUpWinningSide;
@@ -43904,6 +43980,16 @@ function setMatchUpHomeParticipantId(params) {
43904
43980
  });
43905
43981
  }
43906
43982
 
43983
+ function matchUpTimeModifiers({ timeStamp, schedule, matchUp }) {
43984
+ const { itemValue: timeModifiers, timeStamp: itemTimeStamp } = latestVisibleTimeItemValue({
43985
+ timeItems: matchUp?.timeItems || [],
43986
+ itemType: TIME_MODIFIERS,
43987
+ });
43988
+ return !schedule || (itemTimeStamp && timeStamp && new Date(itemTimeStamp).getTime() > new Date(timeStamp).getTime())
43989
+ ? { timeModifiers }
43990
+ : schedule;
43991
+ }
43992
+
43907
43993
  function addMatchUpScheduledTime(params) {
43908
43994
  const stack = 'addMatchUpScheduledTime';
43909
43995
  let matchUp = params.matchUp;
@@ -49225,8 +49311,8 @@ function generateOutcome(params) {
49225
49311
  winningSide = winningSide || randomInt(1, 2);
49226
49312
  const outcome = {
49227
49313
  score: noScore,
49228
- winningSide,
49229
49314
  matchUpStatus,
49315
+ winningSide,
49230
49316
  };
49231
49317
  const scoreDefaulted = matchUpStatus === DEFAULTED && randomInt(1, 100) > 100 - defaultWithScorePercent;
49232
49318
  if (!scoreDefaulted)
@@ -49236,49 +49322,46 @@ function generateOutcome(params) {
49236
49322
  return { outcome: { score: noScore, matchUpStatus } };
49237
49323
  }
49238
49324
  const parsedFormat = parse(matchUpFormat);
49239
- const { bestOf, setFormat, finalSetFormat } = parsedFormat ?? {};
49325
+ const { bestOf = 1, exactly, setFormat, finalSetFormat } = parsedFormat ?? {};
49240
49326
  const sets = [];
49241
49327
  const weightedSide = randomInt(0, 1);
49242
49328
  const weightedRange = winningSide
49243
49329
  ? [winningSide - 1]
49244
49330
  : [...generateRange(0, sideWeight).map(() => weightedSide), 1 - weightedSide];
49245
49331
  const incompleteSet = [RETIRED$1, DEFAULTED, INCOMPLETE, SUSPENDED].includes(matchUpStatus);
49246
- const incompleteAt = incompleteSet && (randomPop(generateRange(1, bestOf)) || 1);
49332
+ const incompleteAt = incompleteSet && (randomPop(generateRange(1, exactly || bestOf)) || 1);
49247
49333
  let weightedWinningSide;
49248
- for (const setNumber of generateRange(1, (bestOf ?? 0) + 1)) {
49249
- const isFinalSet = setNumber === bestOf;
49334
+ const setsToGenerate = generateRange(1, (exactly ?? bestOf) + 1);
49335
+ for (const setNumber of setsToGenerate) {
49336
+ const isFinalSet = setNumber === (exactly ?? bestOf);
49250
49337
  const { set, incomplete, winningSideNumber } = generateSet({
49338
+ setFormat: (isFinalSet && finalSetFormat) || setFormat,
49251
49339
  incomplete: incompleteAt === setNumber,
49252
- matchUpStatus,
49253
49340
  pointsPerMinute,
49254
- setFormat: (isFinalSet && finalSetFormat) || setFormat,
49255
- setNumber,
49341
+ matchUpStatus,
49256
49342
  weightedRange,
49343
+ setNumber,
49257
49344
  });
49258
49345
  sets.push(set);
49259
49346
  if (incomplete) {
49260
49347
  weightedWinningSide = winningSideNumber;
49261
49348
  break;
49262
49349
  }
49263
- const analysis = analyzeMatchUp({
49264
- matchUp: { score: { sets }, matchUpFormat },
49265
- });
49350
+ const analysis = analyzeMatchUp({ matchUp: { score: { sets }, matchUpFormat } });
49266
49351
  if (analysis.calculatedWinningSide)
49267
49352
  break;
49268
49353
  }
49269
- const analysis = analyzeMatchUp({
49270
- matchUp: { score: { sets }, matchUpFormat },
49271
- });
49354
+ const analysis = analyzeMatchUp({ matchUp: { score: { sets }, matchUpFormat, winningSide } });
49272
49355
  const matchUpWinningSide = weightedWinningSide ? winningSide || weightedWinningSide : analysis.calculatedWinningSide;
49273
49356
  const { score } = matchUpScore({
49274
- score: { sets },
49275
49357
  winningSide: matchUpWinningSide,
49358
+ score: { sets },
49276
49359
  matchUpStatus,
49277
49360
  });
49278
49361
  const outcome = {
49279
- score,
49280
49362
  winningSide: matchUpWinningSide,
49281
49363
  matchUpStatus,
49364
+ score,
49282
49365
  };
49283
49366
  return { outcome };
49284
49367
  }
@@ -49404,13 +49487,8 @@ function completeDrawMatchUps(params) {
49404
49487
  const sortedStructures = drawDefinition.structures.slice().sort(structureSort);
49405
49488
  let completedCount = 0;
49406
49489
  const { matchUps: firstRoundDualMatchUps, matchUpsMap } = getAllDrawMatchUps({
49407
- contextFilters: {
49408
- stages: [MAIN, QUALIFYING],
49409
- },
49410
- matchUpFilters: {
49411
- matchUpTypes: [TEAM$2],
49412
- roundNumbers: [1],
49413
- },
49490
+ matchUpFilters: { matchUpTypes: [TEAM$2], roundNumbers: [1] },
49491
+ contextFilters: { stages: [MAIN, QUALIFYING] },
49414
49492
  inContext: true,
49415
49493
  drawDefinition,
49416
49494
  });
@@ -49504,11 +49582,16 @@ function completeDrawMatchUps(params) {
49504
49582
  }
49505
49583
  const scoreString = typeof completeAllMatchUps === 'string' && completeAllMatchUps;
49506
49584
  const matchUpStatus = scoreString && COMPLETED$1;
49507
- for (const structure of sortedStructures) {
49585
+ const isRoundRobinWithPlayoff = sortedStructures.length === 2 &&
49586
+ sortedStructures[0].finishingPosition === WIN_RATIO$1 &&
49587
+ intersection(sortedStructures.map(({ stage }) => stage), [MAIN, PLAY_OFF]).length === 2;
49588
+ const structureIds = sortedStructures.map(({ structureId }) => structureId);
49589
+ for (const structureId of structureIds) {
49508
49590
  if (completedCount >= completionGoal)
49509
49591
  break;
49510
- const { matchUps } = getAllStructureMatchUps({
49511
- matchUpFilters: { matchUpTypes: [DOUBLES$1, SINGLES$1] },
49592
+ const structure = drawDefinition.structures.find((structure) => structure.structureId === structureId);
49593
+ const matchUps = getAllStructureMatchUps({
49594
+ contextFilters: { matchUpTypes: [DOUBLES$1, SINGLES$1] },
49512
49595
  afterRecoveryTimes: false,
49513
49596
  tournamentRecord,
49514
49597
  inContext: true,
@@ -49516,7 +49599,10 @@ function completeDrawMatchUps(params) {
49516
49599
  matchUpsMap,
49517
49600
  structure,
49518
49601
  event,
49519
- });
49602
+ }).matchUps;
49603
+ if (!matchUps.length) {
49604
+ console.log('##', drawDefinition);
49605
+ }
49520
49606
  const sortedMatchUpIds = matchUps
49521
49607
  .filter(({ winningSide }) => !winningSide)
49522
49608
  .sort(matchUpSort)
@@ -49537,8 +49623,8 @@ function completeDrawMatchUps(params) {
49537
49623
  const targetMatchUp = matchUps.find((matchUp) => matchUp.matchUpId === matchUpId);
49538
49624
  const isDoubleExit = [DOUBLE_WALKOVER, DOUBLE_DEFAULT].includes(targetMatchUp.matchUpStatus);
49539
49625
  if (targetMatchUp?.readyToScore && !isDoubleExit) {
49626
+ const winningSide = !randomWinningSide && 1;
49540
49627
  const result = smartComplete({
49541
- winningSide: !randomWinningSide && 1,
49542
49628
  matchUpStatusProfile,
49543
49629
  tournamentRecord,
49544
49630
  drawDefinition,
@@ -49546,6 +49632,7 @@ function completeDrawMatchUps(params) {
49546
49632
  matchUpFormat,
49547
49633
  matchUpStatus,
49548
49634
  scoreString,
49635
+ winningSide,
49549
49636
  event,
49550
49637
  });
49551
49638
  if (result?.error)
@@ -49553,6 +49640,13 @@ function completeDrawMatchUps(params) {
49553
49640
  completedCount += 1;
49554
49641
  }
49555
49642
  }
49643
+ if (isRoundRobinWithPlayoff && structure.finishingPosition === WIN_RATIO$1 && params.completeRoundRobinPlayoffs) {
49644
+ automatedPlayoffPositioning({
49645
+ structureId: structure.structureId,
49646
+ applyPositioning: true,
49647
+ drawDefinition,
49648
+ });
49649
+ }
49556
49650
  }
49557
49651
  return { ...SUCCESS, completedCount };
49558
49652
  }
@@ -56514,17 +56608,27 @@ function copyTournamentRecord(params) {
56514
56608
  const tournamentDayMilliseconds = startDate && endDate ? new Date(extractDate(endDate)).getTime() - new Date(extractDate(startDate)).getTime() : 0;
56515
56609
  const tournamentDays = tournamentDayMilliseconds / dayMilliseconds;
56516
56610
  const newEndDate = params.endDate || addDays(params.startDate, tournamentDays);
56611
+ const filteredTimeItems = (timeItems) => timeItems?.filter(({ itemType }) => params.itemTypeList?.includes(itemType));
56612
+ const filteredExtensions = (extensions) => extensions?.filter(({ name }) => params.extensionList?.includes(name));
56517
56613
  const copyParticipant = (participant) => {
56518
- const { timeItems, ...rest } = participant;
56519
- return { ...rest };
56614
+ const { timeItems, extensions, ...rest } = participant;
56615
+ return makeDeepCopy({ ...rest, timeItems: filteredTimeItems(timeItems), extensions: filteredExtensions(extensions) }, false, true);
56520
56616
  };
56521
56617
  const copyEvent = (event) => {
56522
- const { drawDefinitions, ...rest } = event;
56523
- return { ...rest };
56618
+ const { drawDefinitions, timeItems, extensions, startDate, endDate, ...rest } = event;
56619
+ return makeDeepCopy({
56620
+ extensions: filteredExtensions(extensions),
56621
+ timeItems: filteredTimeItems(timeItems),
56622
+ startDate: params.startDate,
56623
+ endDate: newEndDate,
56624
+ ...rest,
56625
+ }, false, true);
56524
56626
  };
56525
56627
  const tournamentRecord = {
56526
56628
  participants: params.copyParticipants ? params.tournamentRecord.participants?.map(copyParticipant) ?? [] : [],
56527
- parentOrganisation: { ...params.tournamentRecord.parentOrganisation },
56629
+ parentOrganisation: makeDeepCopy({ ...params.tournamentRecord.parentOrganisation }, false, true),
56630
+ extensions: filteredExtensions(params.tournamentRecord.extensions),
56631
+ timeItems: filteredTimeItems(params.tournamentRecord.timeItems),
56528
56632
  events: params.tournamentRecord.events?.map(copyEvent) ?? [],
56529
56633
  weekdays: { ...params.tournamentRecord.weekdays },
56530
56634
  venues: { ...params.tournamentRecord.venues },