tods-competition-factory 2.2.18 → 2.2.20

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.18';
6
+ return '2.2.20';
7
7
  }
8
8
 
9
9
  const SINGLES_MATCHUP = 'SINGLES';
@@ -585,6 +585,10 @@ const MISSING_STRUCTURE = {
585
585
  message: 'Missing structure',
586
586
  code: 'ERR_MISSING_STRUCTURE',
587
587
  };
588
+ const MISSING_MAIN_STRUCTURE = {
589
+ message: 'Missing MAIN structure',
590
+ code: 'ERR_MISSING_MAIN_STRUCTURE',
591
+ };
588
592
  const UNLINKED_STRUCTURES = {
589
593
  message: 'drawDefinition contains unlinked structures',
590
594
  code: 'ERR_MISSING_STRUCTURE_LINKS',
@@ -873,6 +877,10 @@ const MISSING_PARTICIPANT_ID = {
873
877
  message: 'Missing participantId',
874
878
  code: 'ERR_MISSING_PARTICIPANT_ID',
875
879
  };
880
+ const MISSING_QUALIFIED_PARTICIPANTS = {
881
+ message: 'Missing qualified participants',
882
+ code: 'ERR_MISSING_QUALIFIED_PARTICIPANTS',
883
+ };
876
884
  const PARTICIPANT_NOT_FOUND = {
877
885
  message: 'Participant Not Found',
878
886
  code: 'ERR_NOT_FOUND_PARTICIPANT',
@@ -1241,6 +1249,7 @@ const errorConditionConstants = {
1241
1249
  MISSING_DRAW_SIZE,
1242
1250
  MISSING_ENTRIES,
1243
1251
  MISSING_EVENT,
1252
+ MISSING_QUALIFIED_PARTICIPANTS,
1244
1253
  MISSING_MATCHUP_FORMAT,
1245
1254
  MISSING_MATCHUP_ID,
1246
1255
  MISSING_MATCHUP_IDS,
@@ -1271,6 +1280,7 @@ const errorConditionConstants = {
1271
1280
  MISSING_STAGE,
1272
1281
  MISSING_STRUCTURE_ID,
1273
1282
  MISSING_STRUCTURE,
1283
+ MISSING_MAIN_STRUCTURE,
1274
1284
  MISSING_STRUCTURES,
1275
1285
  MISSING_TARGET_LINK,
1276
1286
  MISSING_TIE_FORMAT,
@@ -10261,14 +10271,14 @@ function addMatchUpContext({ scheduleVisibilityFilters, sourceDrawPositionRanges
10261
10271
  tournamentRecord?.processCodes;
10262
10272
  const competitiveProfile = contextProfile?.withCompetitiveness && getMatchUpCompetitiveProfile({ ...contextContent, matchUp });
10263
10273
  const finishingPositionRange = matchUp.finishingPositionRange ?? additionalContext.finishingPositionRange;
10274
+ const roundOfPlay = stage !== QUALIFYING && isConvertableInteger(initialRoundOfPlay) && initialRoundOfPlay + (roundNumber || 0);
10264
10275
  const onlyDefined = (obj) => definedAttributes(obj, undefined, true);
10265
10276
  const matchUpWithContext = {
10266
10277
  ...onlyDefined(context),
10267
10278
  ...onlyDefined({
10268
- matchUpFormat: matchUp.matchUpType === TEAM$1 ? undefined : matchUpFormat,
10269
- tieFormat: matchUp.matchUpType !== TEAM$1 ? undefined : tieFormat,
10279
+ matchUpFormat: matchUpType === TEAM$1 ? undefined : matchUpFormat,
10280
+ tieFormat: matchUpType !== TEAM$1 ? undefined : tieFormat,
10270
10281
  gender: collectionDefinition?.gender ?? event?.gender,
10271
- roundOfPlay: stage !== QUALIFYING && isConvertableInteger(initialRoundOfPlay) && initialRoundOfPlay + (roundNumber || 0),
10272
10282
  endDate: matchUp.endDate ?? endDate,
10273
10283
  discipline: event?.discipline,
10274
10284
  category: matchUpCategory,
@@ -10289,6 +10299,7 @@ function addMatchUpContext({ scheduleVisibilityFilters, sourceDrawPositionRanges
10289
10299
  roundOffset,
10290
10300
  structureId,
10291
10301
  roundNumber,
10302
+ roundOfPlay,
10292
10303
  feedRound,
10293
10304
  roundName,
10294
10305
  drawName,
@@ -17435,22 +17446,6 @@ function swapAdHocRounds(params) {
17435
17446
  return { ...SUCCESS };
17436
17447
  }
17437
17448
 
17438
- function qualifierDrawPositionAssignment$1({ qualifyingParticipantId, tournamentRecord, drawDefinition, drawPosition, structureId, }) {
17439
- return positionParticipantAction({
17440
- positionActionName: 'qualifierDrawPositionAssignment',
17441
- participantId: qualifyingParticipantId,
17442
- isQualifierPosition: true,
17443
- tournamentRecord,
17444
- drawDefinition,
17445
- drawPosition,
17446
- structureId,
17447
- });
17448
- }
17449
-
17450
- function qualifierDrawPositionAssignment(params) {
17451
- return qualifierDrawPositionAssignment$1(params);
17452
- }
17453
-
17454
17449
  function alternateDrawPositionAssignment({ alternateParticipantId, tournamentRecord, drawDefinition, drawPosition, structureId, event, }) {
17455
17450
  return positionParticipantAction({
17456
17451
  positionActionName: 'alternateDrawPositionAssignment',
@@ -17464,60 +17459,6 @@ function alternateDrawPositionAssignment({ alternateParticipantId, tournamentRec
17464
17459
  });
17465
17460
  }
17466
17461
 
17467
- function modifySeedAssignment({ validation = true, tournamentRecord, drawDefinition, participantId, structureId, seedValue, event, }) {
17468
- if (!drawDefinition)
17469
- return { error: MISSING_DRAW_DEFINITION };
17470
- if (!structureId)
17471
- return { error: MISSING_STRUCTURE_ID };
17472
- const participant = (tournamentRecord?.participants ?? []).find((participant) => participant.participantId === participantId);
17473
- if (tournamentRecord && !participant)
17474
- return { error: INVALID_PARTICIPANT_ID };
17475
- const { structure } = findStructure({ drawDefinition, structureId });
17476
- if (!structure)
17477
- return { error: STRUCTURE_NOT_FOUND };
17478
- const validValue = !validation ||
17479
- isNumeric(seedValue) ||
17480
- seedValue === undefined ||
17481
- seedValue === '' ||
17482
- (typeof seedValue === 'string' && seedValue.split('-').every((v) => isNumeric(v) && ensureInt(v) > 0));
17483
- if (!validValue)
17484
- return { error: INVALID_VALUES };
17485
- const { seedAssignments } = getStructureSeedAssignments({
17486
- drawDefinition,
17487
- structure,
17488
- });
17489
- const seedNumbers = seedAssignments?.map((assignment) => assignment.seedNumber);
17490
- const existingAssginment = seedAssignments?.find((assignment) => assignment.participantId === participantId);
17491
- if (existingAssginment) {
17492
- const newValue = typeof seedValue === 'string'
17493
- ? (seedValue.includes('-') &&
17494
- seedValue
17495
- .split('-')
17496
- .map((v) => parseInt(v))
17497
- .join('-')) ||
17498
- (parseInt(seedValue) > 0 && parseInt(seedValue)) ||
17499
- ''
17500
- : (seedValue && seedValue > 0 && seedValue) || '';
17501
- existingAssginment.seedValue = newValue;
17502
- }
17503
- else {
17504
- const seedNumber = Math.max(0, ...(seedNumbers || [])) + 1;
17505
- const seedAssignment = { seedNumber, participantId };
17506
- if (seedValue)
17507
- seedAssignment.seedValue = seedValue;
17508
- if (!structure.seedAssignments)
17509
- structure.seedAssignments = [];
17510
- structure.seedAssignments.push(seedAssignment);
17511
- }
17512
- modifySeedAssignmentsNotice({
17513
- tournamentId: tournamentRecord?.tournamentId,
17514
- eventId: event?.eventId,
17515
- drawDefinition,
17516
- structure,
17517
- });
17518
- return { ...SUCCESS };
17519
- }
17520
-
17521
17462
  function getPlayoffStructures({ drawDefinition, structureId }) {
17522
17463
  if (!drawDefinition)
17523
17464
  return { error: MISSING_DRAW_DEFINITION };
@@ -18597,21 +18538,7 @@ function getStructurePositionedSeeds({ provisionalPositioning, drawDefinition, s
18597
18538
 
18598
18539
  function getBlockSortedRandomDrawPositions({ orderedSortedFirstRoundSeededDrawPositions: strictOrder, validSeedBlocks, byesToPlace, }) {
18599
18540
  const drawPositions = [];
18600
- validSeedBlocks.forEach((seedBlock) => {
18601
- const leftToPlace = byesToPlace - drawPositions.length;
18602
- if (leftToPlace > seedBlock.drawPositions.length) {
18603
- drawPositions.push(...seedBlock.drawPositions);
18604
- }
18605
- else {
18606
- const nestedDrawPositions = nestArray(chunkArray(seedBlock.drawPositions, 2));
18607
- let drawPosition;
18608
- let desiredPosition = strictOrder[drawPositions.length];
18609
- while ((drawPosition = popFromLargerSide(nestedDrawPositions, desiredPosition))) {
18610
- drawPositions.push(drawPosition);
18611
- desiredPosition = strictOrder[drawPositions.length];
18612
- }
18613
- }
18614
- });
18541
+ validSeedBlocks.forEach((seedBlock) => processSeedBlock(seedBlock, byesToPlace, drawPositions, strictOrder));
18615
18542
  const blockSortedRandom = drawPositions.map((p) => (Array.isArray(p) ? shuffleArray(p) : p)).flat(Infinity);
18616
18543
  if (isOdd(byesToPlace)) {
18617
18544
  const blockFirstSeedNumbers = validSeedBlocks.map((block) => block.seedNumbers[0]);
@@ -18620,14 +18547,38 @@ function getBlockSortedRandomDrawPositions({ orderedSortedFirstRoundSeededDrawPo
18620
18547
  }
18621
18548
  return blockSortedRandom;
18622
18549
  }
18550
+ function processSeedBlock(seedBlock, byesToPlace, drawPositions, strictOrder) {
18551
+ const leftToPlace = byesToPlace - drawPositions.length;
18552
+ if (leftToPlace > seedBlock.drawPositions.length) {
18553
+ drawPositions.push(...seedBlock.drawPositions);
18554
+ }
18555
+ else {
18556
+ const nestedDrawPositions = nestArray(chunkArray(seedBlock.drawPositions, 2));
18557
+ placeDrawPositions(nestedDrawPositions, drawPositions, strictOrder);
18558
+ }
18559
+ }
18560
+ function placeDrawPositions(nestedDrawPositions, drawPositions, strictOrder) {
18561
+ let drawPosition;
18562
+ let desiredPosition = strictOrder[drawPositions.length];
18563
+ while ((drawPosition = popFromLargerSide(nestedDrawPositions, desiredPosition))) {
18564
+ drawPositions.push(drawPosition);
18565
+ desiredPosition = strictOrder[drawPositions.length];
18566
+ }
18567
+ }
18623
18568
  function popFromLargerSide(arr, desiredPosition) {
18624
18569
  if (Array.isArray(arr) && arr.length !== 2)
18625
18570
  return arr.pop();
18626
18571
  if (!Array.isArray(arr[0])) {
18627
- if (arr.includes(desiredPosition))
18628
- return arr.indexOf(desiredPosition) ? arr.pop() : arr.shift();
18629
- return Math.round(Math.random()) ? arr.pop() : arr.shift();
18572
+ return handleNonNestedArray(arr, desiredPosition);
18630
18573
  }
18574
+ return handleNestedArray(arr, desiredPosition);
18575
+ }
18576
+ function handleNonNestedArray(arr, desiredPosition) {
18577
+ if (arr.includes(desiredPosition))
18578
+ return arr.indexOf(desiredPosition) ? arr.pop() : arr.shift();
18579
+ return Math.round(Math.random()) ? arr.pop() : arr.shift();
18580
+ }
18581
+ function handleNestedArray(arr, desiredPosition) {
18631
18582
  const side1 = arr[0].flat(Infinity).length;
18632
18583
  const side2 = arr[1].flat(Infinity).length;
18633
18584
  if (side1 === side2) {
@@ -19225,6 +19176,197 @@ function automatedPlayoffPositioning(params) {
19225
19176
  return { ...SUCCESS, structurePositionAssignments, positioningReports };
19226
19177
  }
19227
19178
 
19179
+ function modifySeedAssignment({ validation = true, tournamentRecord, drawDefinition, participantId, structureId, seedValue, event, }) {
19180
+ if (!drawDefinition)
19181
+ return { error: MISSING_DRAW_DEFINITION };
19182
+ if (!structureId)
19183
+ return { error: MISSING_STRUCTURE_ID };
19184
+ const participant = (tournamentRecord?.participants ?? []).find((participant) => participant.participantId === participantId);
19185
+ if (tournamentRecord && !participant)
19186
+ return { error: INVALID_PARTICIPANT_ID };
19187
+ const { structure } = findStructure({ drawDefinition, structureId });
19188
+ if (!structure)
19189
+ return { error: STRUCTURE_NOT_FOUND };
19190
+ const validValue = !validation ||
19191
+ isNumeric(seedValue) ||
19192
+ seedValue === undefined ||
19193
+ seedValue === '' ||
19194
+ (typeof seedValue === 'string' && seedValue.split('-').every((v) => isNumeric(v) && ensureInt(v) > 0));
19195
+ if (!validValue)
19196
+ return { error: INVALID_VALUES };
19197
+ const { seedAssignments } = getStructureSeedAssignments({
19198
+ drawDefinition,
19199
+ structure,
19200
+ });
19201
+ const seedNumbers = seedAssignments?.map((assignment) => assignment.seedNumber);
19202
+ const existingAssginment = seedAssignments?.find((assignment) => assignment.participantId === participantId);
19203
+ if (existingAssginment) {
19204
+ const newValue = typeof seedValue === 'string'
19205
+ ? (seedValue.includes('-') &&
19206
+ seedValue
19207
+ .split('-')
19208
+ .map((v) => parseInt(v))
19209
+ .join('-')) ||
19210
+ (parseInt(seedValue) > 0 && parseInt(seedValue)) ||
19211
+ ''
19212
+ : (seedValue && seedValue > 0 && seedValue) || '';
19213
+ existingAssginment.seedValue = newValue;
19214
+ }
19215
+ else {
19216
+ const seedNumber = Math.max(0, ...(seedNumbers || [])) + 1;
19217
+ const seedAssignment = { seedNumber, participantId };
19218
+ if (seedValue)
19219
+ seedAssignment.seedValue = seedValue;
19220
+ if (!structure.seedAssignments)
19221
+ structure.seedAssignments = [];
19222
+ structure.seedAssignments.push(seedAssignment);
19223
+ }
19224
+ modifySeedAssignmentsNotice({
19225
+ tournamentId: tournamentRecord?.tournamentId,
19226
+ eventId: event?.eventId,
19227
+ drawDefinition,
19228
+ structure,
19229
+ });
19230
+ return { ...SUCCESS };
19231
+ }
19232
+
19233
+ function qualifierDrawPositionAssignment({ qualifyingParticipantId, tournamentRecord, drawDefinition, drawPosition, structureId, }) {
19234
+ return positionParticipantAction({
19235
+ positionActionName: 'qualifierDrawPositionAssignment',
19236
+ participantId: qualifyingParticipantId,
19237
+ isQualifierPosition: true,
19238
+ tournamentRecord,
19239
+ drawDefinition,
19240
+ drawPosition,
19241
+ structureId,
19242
+ });
19243
+ }
19244
+
19245
+ function getSourceStructureIdsAndRelevantLinks({ targetRoundNumber, finishingPosition, drawDefinition, structureId, linkType, }) {
19246
+ const { links } = getStructureLinks({
19247
+ drawDefinition,
19248
+ structureId,
19249
+ }) || {};
19250
+ const sourceLinks = (links?.target || [])
19251
+ .filter(({ linkType: structureLinkType }) => structureLinkType === linkType)
19252
+ .filter(({ target }) => !targetRoundNumber || targetRoundNumber === target.roundNumber);
19253
+ const relevantLinks = sourceLinks
19254
+ .map((link) => {
19255
+ const sourceStructureId = link.source.structureId;
19256
+ const { structure: sourceStructure } = findStructure({
19257
+ structureId: sourceStructureId,
19258
+ drawDefinition,
19259
+ });
19260
+ if (finishingPosition && sourceStructure?.finishingPosition !== finishingPosition)
19261
+ return undefined;
19262
+ return link;
19263
+ })
19264
+ .filter(Boolean);
19265
+ const sourceStructureIds = relevantLinks.map(({ source }) => source.structureId);
19266
+ return { sourceStructureIds, relevantLinks };
19267
+ }
19268
+
19269
+ function qualifierProgression({ targetRoundNumber = 1, tournamentRecord, drawDefinition, event, }) {
19270
+ const paramsCheck = checkRequiredParameters({ drawDefinition, event, tournamentRecord }, [
19271
+ { [DRAW_DEFINITION]: true, [EVENT]: true, [TOURNAMENT_RECORD]: true },
19272
+ ]);
19273
+ if (paramsCheck.error)
19274
+ return paramsCheck;
19275
+ const assignedParticipants = [];
19276
+ const qualifyingParticipantIds = [];
19277
+ const mainStructure = drawDefinition.structures?.find((structure) => structure.stage === MAIN && structure.stageSequence === 1);
19278
+ if (!mainStructure)
19279
+ return decorateResult({ result: { error: MISSING_MAIN_STRUCTURE } });
19280
+ const appliedPolicies = getAppliedPolicies({ tournamentRecord, drawDefinition, structure: mainStructure, event }).appliedPolicies ?? {};
19281
+ const policy = appliedPolicies[POLICY_TYPE_POSITION_ACTIONS];
19282
+ const requireCompletedStructures = policy?.requireCompletedStructures;
19283
+ const { qualifierPositions, positionAssignments } = structureAssignedDrawPositions({ structure: mainStructure });
19284
+ if (!qualifierPositions.length)
19285
+ return decorateResult({ result: { error: NO_DRAW_POSITIONS_AVAILABLE_FOR_QUALIFIERS } });
19286
+ const assignedParticipantIds = positionAssignments.map((assignment) => assignment.participantId).filter(Boolean);
19287
+ const { relevantLinks: eliminationSourceLinks } = getSourceStructureIdsAndRelevantLinks({
19288
+ structureId: mainStructure.structureId,
19289
+ targetRoundNumber,
19290
+ linkType: WINNER,
19291
+ drawDefinition,
19292
+ }) || {};
19293
+ const { relevantLinks: roundRobinSourceLinks } = getSourceStructureIdsAndRelevantLinks({
19294
+ structureId: mainStructure.structureId,
19295
+ targetRoundNumber,
19296
+ linkType: POSITION,
19297
+ drawDefinition,
19298
+ }) || {};
19299
+ for (const sourceLink of eliminationSourceLinks) {
19300
+ const structure = drawDefinition.structures?.find((structure) => structure.structureId === sourceLink.source.structureId);
19301
+ if (structure?.stage !== QUALIFYING)
19302
+ continue;
19303
+ const structureCompleted = isCompletedStructure({ structureId: sourceLink.source.structureId, drawDefinition });
19304
+ if (!requireCompletedStructures || structureCompleted) {
19305
+ const qualifyingRoundNumber = structure.qualifyingRoundNumber;
19306
+ const { matchUps } = getAllStructureMatchUps({
19307
+ matchUpFilters: {
19308
+ ...(qualifyingRoundNumber && { roundNumbers: [qualifyingRoundNumber] }),
19309
+ hasWinningSide: true,
19310
+ },
19311
+ afterRecoveryTimes: false,
19312
+ inContext: true,
19313
+ structure,
19314
+ });
19315
+ for (const matchUp of matchUps) {
19316
+ const relevantSide = matchUp.matchUpStatus === BYE && matchUp.sides?.find(({ participantId }) => participantId);
19317
+ const winningSide = matchUp.sides.find((side) => side?.sideNumber === matchUp.winningSide);
19318
+ if (winningSide || relevantSide) {
19319
+ const { participantId } = winningSide || relevantSide || {};
19320
+ if (participantId && !assignedParticipantIds.includes(participantId)) {
19321
+ qualifyingParticipantIds.push(participantId);
19322
+ }
19323
+ }
19324
+ }
19325
+ }
19326
+ }
19327
+ for (const sourceLink of roundRobinSourceLinks) {
19328
+ const structure = drawDefinition?.structures?.find((structure) => structure.structureId === sourceLink.source.structureId);
19329
+ if (structure?.stage !== QUALIFYING)
19330
+ continue;
19331
+ const structureCompleted = isCompletedStructure({
19332
+ structureId: sourceLink.source.structureId,
19333
+ drawDefinition,
19334
+ });
19335
+ if (structureCompleted) {
19336
+ const { positionAssignments } = getPositionAssignments$1({ structure });
19337
+ const relevantParticipantIds = positionAssignments
19338
+ ?.map((assignment) => {
19339
+ const participantId = assignment.participantId;
19340
+ const results = findExtension({ element: assignment, name: TALLY }).extension?.value;
19341
+ return results ? { participantId, groupOrder: results?.groupOrder } : {};
19342
+ })
19343
+ .filter(({ groupOrder, participantId }) => groupOrder === 1 && !assignedParticipantIds.includes(participantId))
19344
+ .map(({ participantId }) => participantId) ?? [];
19345
+ if (relevantParticipantIds)
19346
+ qualifyingParticipantIds.push(...relevantParticipantIds);
19347
+ }
19348
+ }
19349
+ if (!qualifyingParticipantIds.length)
19350
+ return decorateResult({ result: { error: MISSING_QUALIFIED_PARTICIPANTS } });
19351
+ qualifierPositions.forEach((position) => {
19352
+ const randomParticipantId = randomPop(qualifyingParticipantIds);
19353
+ if (randomParticipantId) {
19354
+ const positionAssignmentResult = qualifierDrawPositionAssignment({
19355
+ qualifyingParticipantId: randomParticipantId,
19356
+ structureId: mainStructure.structureId,
19357
+ drawPosition: position.drawPosition,
19358
+ tournamentRecord,
19359
+ drawDefinition,
19360
+ });
19361
+ positionAssignmentResult?.success &&
19362
+ assignedParticipants.push({ participantId: randomParticipantId, drawPosition: position.drawPosition });
19363
+ }
19364
+ });
19365
+ return decorateResult({
19366
+ result: definedAttributes({ ...SUCCESS, assignedParticipants }),
19367
+ });
19368
+ }
19369
+
19228
19370
  function setStructureOrder({ drawDefinition, orderMap }) {
19229
19371
  if (!drawDefinition)
19230
19372
  return { error: MISSING_DRAW_DEFINITION };
@@ -21930,7 +22072,7 @@ function isGamesBased(based) {
21930
22072
  return !isPointsBased(based);
21931
22073
  }
21932
22074
 
21933
- function calculatePercentages({ participantResults, matchUpFormat, tallyPolicy, perPlayer, totalSets }) {
22075
+ function calculatePercentages({ participantResults, groupingTotal, matchUpFormat, tallyPolicy, totalGames, perPlayer, totalSets, }) {
21934
22076
  const parsedGroupMatchUpFormat = (matchUpFormat && parse(matchUpFormat)) || {};
21935
22077
  const bestOfGames = parsedGroupMatchUpFormat.bestOf;
21936
22078
  const bracketSetsToWin = (bestOfGames && Math.ceil(bestOfGames / 2)) || 1;
@@ -21939,7 +22081,7 @@ function calculatePercentages({ participantResults, matchUpFormat, tallyPolicy,
21939
22081
  Object.keys(participantResults).forEach((participantId) => {
21940
22082
  const setsWon = participantResults[participantId].setsWon;
21941
22083
  const setsLost = participantResults[participantId].setsLost;
21942
- const setsTotal = tallyPolicy?.groupTotalSetsPlayed
22084
+ const setsTotal = tallyPolicy?.groupTotalSetsPlayed || groupingTotal === 'setsPct'
21943
22085
  ? totalSets
21944
22086
  : perPlayer * (bracketSetsToWin || 0) || setsWon + setsLost;
21945
22087
  let setsPct = Math.round((setsWon / setsTotal) * precision) / precision;
@@ -21960,7 +22102,9 @@ function calculatePercentages({ participantResults, matchUpFormat, tallyPolicy,
21960
22102
  const gamesWon = participantResults[participantId].gamesWon || 0;
21961
22103
  const gamesLost = participantResults[participantId].gamesLost || 0;
21962
22104
  const minimumExpectedGames = (perPlayer || 0) * (bracketSetsToWin || 0) * (bracketGamesForSet || 0);
21963
- const gamesTotal = Math.max(minimumExpectedGames, gamesWon + gamesLost);
22105
+ const gamesTotal = tallyPolicy?.groupTotalGamesPlayed || groupingTotal === 'gamesPct'
22106
+ ? totalGames
22107
+ : Math.max(minimumExpectedGames, gamesWon + gamesLost);
21964
22108
  let gamesPct = Math.round((gamesWon / gamesTotal) * precision) / precision;
21965
22109
  if (gamesPct === Infinity || isNaN(gamesPct))
21966
22110
  gamesPct = 0;
@@ -21983,7 +22127,7 @@ function calculatePercentages({ participantResults, matchUpFormat, tallyPolicy,
21983
22127
  });
21984
22128
  }
21985
22129
 
21986
- function getParticipantResults({ participantIds, pressureRating, matchUpFormat, tallyPolicy, perPlayer, matchUps, }) {
22130
+ function getParticipantResults({ participantIds, pressureRating, groupingTotal, matchUpFormat, tallyPolicy, perPlayer, matchUps, }) {
21987
22131
  const participantResults = {};
21988
22132
  const excludeMatchUpStatuses = tallyPolicy?.excludeMatchUpStatuses || [];
21989
22133
  const filteredMatchUps = matchUps?.filter((matchUp) => {
@@ -21991,12 +22135,19 @@ function getParticipantResults({ participantIds, pressureRating, matchUpFormat,
21991
22135
  (!participantIds?.length ||
21992
22136
  intersection(participantIds, [getSideId(matchUp, 0), getSideId(matchUp, 1)]).length === 2));
21993
22137
  });
21994
- const allSets = filteredMatchUps?.flatMap(({ score, tieMatchUps }) => tieMatchUps
22138
+ const allSetsCount = filteredMatchUps?.flatMap(({ score, tieMatchUps }) => tieMatchUps
21995
22139
  ? tieMatchUps
21996
22140
  .filter(({ matchUpStatus }) => !excludeMatchUpStatuses.includes(matchUpStatus))
21997
22141
  .flatMap(({ score }) => score?.sets?.length ?? 0)
21998
22142
  : (score?.sets?.length ?? 0));
21999
- const totalSets = allSets?.reduce((a, b) => a + b, 0);
22143
+ const totalSets = allSetsCount?.reduce((a, b) => a + b, 0);
22144
+ const getGames = (score) => score?.sets?.reduce((total, set) => total + (set?.side1Score ?? 0) + (set?.side2Score ?? 0), 0) ?? 0;
22145
+ const allGamesCount = filteredMatchUps?.flatMap(({ score, tieMatchUps }) => tieMatchUps
22146
+ ? tieMatchUps
22147
+ .filter(({ matchUpStatus }) => !excludeMatchUpStatuses.includes(matchUpStatus))
22148
+ .flatMap(({ score }) => getGames(score))
22149
+ : getGames(score));
22150
+ const totalGames = allGamesCount?.reduce((a, b) => a + b, 0);
22000
22151
  for (const matchUp of filteredMatchUps ?? []) {
22001
22152
  const { matchUpStatus, tieMatchUps, tieFormat, score, winningSide, sides } = matchUp;
22002
22153
  const manualGamesOverride = tieFormat && matchUp._disableAutoCalc && tieFormat.collectionDefinitions.every(({ scoreValue }) => scoreValue);
@@ -22140,9 +22291,9 @@ function getParticipantResults({ participantIds, pressureRating, matchUpFormat,
22140
22291
  });
22141
22292
  }
22142
22293
  }
22143
- const gamesWonSide1 = score?.sets?.reduce((total, set) => total + (set?.side1Score ?? 0), 0);
22144
- const gamesWonSide2 = score?.sets?.reduce((total, set) => total + (set.side2Score ?? 0), 0);
22145
22294
  if (manualGamesOverride) {
22295
+ const gamesWonSide1 = score?.sets?.reduce((total, set) => total + (set?.side1Score ?? 0), 0);
22296
+ const gamesWonSide2 = score?.sets?.reduce((total, set) => total + (set.side2Score ?? 0), 0);
22146
22297
  const side1participantId = sides?.find(({ sideNumber }) => sideNumber === 1)?.participantId;
22147
22298
  const side2participantId = sides?.find(({ sideNumber }) => sideNumber === 2)?.participantId;
22148
22299
  checkInitializeParticipant(participantResults, side1participantId);
@@ -22159,8 +22310,10 @@ function getParticipantResults({ participantIds, pressureRating, matchUpFormat,
22159
22310
  }
22160
22311
  calculatePercentages({
22161
22312
  participantResults,
22313
+ groupingTotal,
22162
22314
  matchUpFormat,
22163
22315
  tallyPolicy,
22316
+ totalGames,
22164
22317
  perPlayer,
22165
22318
  totalSets,
22166
22319
  });
@@ -22513,9 +22666,10 @@ function isComplete({ participantResults, participantsCount }) {
22513
22666
  const participantsFinished = resultsArray.filter((r) => participantsCount - 1 === r.results.matchUpsWon + r.results.matchUpsLost + r.results.matchUpsCancelled);
22514
22667
  return participantsCount === participantsFinished.length;
22515
22668
  }
22516
- function processAttribute({ disableHeadToHead, participantIds, matchUpFormat, tallyPolicy, attribute, idsFilter, matchUps, reversed, }) {
22669
+ function processAttribute({ disableHeadToHead, participantIds, matchUpFormat, groupTotals, tallyPolicy, attribute, idsFilter, matchUps, reversed, }) {
22517
22670
  const { participantResults } = getParticipantResults({
22518
22671
  participantIds: idsFilter && participantIds,
22672
+ groupingTotal: groupTotals && attribute,
22519
22673
  matchUpFormat,
22520
22674
  tallyPolicy,
22521
22675
  matchUps,
@@ -22578,11 +22732,12 @@ function groupSubSort({ participantResults, disableHeadToHead, participantIds, m
22578
22732
  });
22579
22733
  if (excludedDirectives.length)
22580
22734
  report.push({ excludedDirectives, participantIds });
22581
- filteredDirectives.every(({ attribute, reversed, idsFilter, disableHeadToHead }) => {
22735
+ filteredDirectives.every(({ attribute, reversed, idsFilter, groupTotals, disableHeadToHead }) => {
22582
22736
  result = processAttribute({
22583
22737
  disableHeadToHead,
22584
22738
  participantIds,
22585
22739
  matchUpFormat,
22740
+ groupTotals,
22586
22741
  tallyPolicy,
22587
22742
  attribute,
22588
22743
  idsFilter,
@@ -22645,8 +22800,8 @@ function tallyParticipantResults({ policyDefinitions, generateReport, pressureRa
22645
22800
  participantResults,
22646
22801
  participantsCount,
22647
22802
  matchUpFormat,
22648
- tallyPolicy,
22649
22803
  subOrderMap,
22804
+ tallyPolicy,
22650
22805
  });
22651
22806
  if (pressureRating)
22652
22807
  addPressureOrder({ participantResults });
@@ -25115,6 +25270,7 @@ var mutate$c = {
25115
25270
  modifySeedAssignment: modifySeedAssignment,
25116
25271
  pruneDrawDefinition: pruneDrawDefinition,
25117
25272
  qualifierDrawPositionAssignment: qualifierDrawPositionAssignment,
25273
+ qualifierProgression: qualifierProgression,
25118
25274
  removeDrawPositionAssignment: removeDrawPositionAssignment,
25119
25275
  removeRoundMatchUps: removeRoundMatchUps,
25120
25276
  removeSeededParticipant: removeSeededParticipant,
@@ -25401,30 +25557,6 @@ function publicFindDrawDefinition(params) {
25401
25557
  return { drawDefinition: makeDeepCopy(drawDefinition) };
25402
25558
  }
25403
25559
 
25404
- function getSourceStructureIdsAndRelevantLinks({ targetRoundNumber, finishingPosition, drawDefinition, structureId, linkType, }) {
25405
- const { links } = getStructureLinks({
25406
- drawDefinition,
25407
- structureId,
25408
- }) || {};
25409
- const sourceLinks = (links?.target || [])
25410
- .filter(({ linkType: structureLinkType }) => structureLinkType === linkType)
25411
- .filter(({ target }) => !targetRoundNumber || targetRoundNumber === target.roundNumber);
25412
- const relevantLinks = sourceLinks
25413
- .map((link) => {
25414
- const sourceStructureId = link.source.structureId;
25415
- const { structure: sourceStructure } = findStructure({
25416
- structureId: sourceStructureId,
25417
- drawDefinition,
25418
- });
25419
- if (finishingPosition && sourceStructure?.finishingPosition !== finishingPosition)
25420
- return undefined;
25421
- return link;
25422
- })
25423
- .filter(Boolean);
25424
- const sourceStructureIds = relevantLinks.map(({ source }) => source.structureId);
25425
- return { sourceStructureIds, relevantLinks };
25426
- }
25427
-
25428
25560
  function getValidModifyAssignedPairAction({ tournamentParticipants, returnParticipants, drawPosition, participant, drawId, event, }) {
25429
25561
  const availableIndividualParticipantIds = event?.entries
25430
25562
  ?.filter(({ entryStatus }) => [UNGROUPED, UNPAIRED].includes(entryStatus))
@@ -38419,6 +38551,7 @@ var index$e = {
38419
38551
  positionActions: positionActions,
38420
38552
  pruneDrawDefinition: pruneDrawDefinition,
38421
38553
  qualifierDrawPositionAssignment: qualifierDrawPositionAssignment,
38554
+ qualifierProgression: qualifierProgression,
38422
38555
  query: query$b,
38423
38556
  removeDrawPositionAssignment: removeDrawPositionAssignment,
38424
38557
  removeRoundMatchUps: removeRoundMatchUps,
@@ -58490,7 +58623,7 @@ function executeFunction(engine, method, params, methodName, engineType) {
58490
58623
  const augmentedParams = params ? paramsMiddleware(tournamentRecords, params) : undefined;
58491
58624
  if (augmentedParams?.error)
58492
58625
  return augmentedParams;
58493
- const result = invoke({
58626
+ const result = invoke$1({
58494
58627
  params: augmentedParams,
58495
58628
  tournamentRecords,
58496
58629
  tournamentRecord,
@@ -58501,7 +58634,7 @@ function executeFunction(engine, method, params, methodName, engineType) {
58501
58634
  engineLogging({ result, methodName, elapsed, params: paramsToLog, engineType });
58502
58635
  return result;
58503
58636
  }
58504
- function invoke({ tournamentRecords, tournamentRecord, params, methodName, method }) {
58637
+ function invoke$1({ tournamentRecords, tournamentRecord, params, methodName, method }) {
58505
58638
  if (getDevContext()) {
58506
58639
  return method({ tournamentRecords, tournamentRecord, ...params });
58507
58640
  }
@@ -59009,58 +59142,58 @@ const matchUpEngine = (() => {
59009
59142
  }
59010
59143
  return engine;
59011
59144
  }
59012
- importGovernors([scoreGovernor]);
59145
+ importGovernors(engine, [scoreGovernor]);
59013
59146
  return engine;
59014
- function importGovernors(governors) {
59015
- governors.forEach((governor) => {
59016
- Object.keys(governor).forEach((methodName) => {
59017
- engine[methodName] = (params) => {
59018
- if (getDevContext()) {
59019
- return invoke({ params, governor, methodName });
59147
+ })();
59148
+ function importGovernors(engine, governors) {
59149
+ governors.forEach((governor) => {
59150
+ Object.keys(governor).forEach((methodName) => {
59151
+ engine[methodName] = (params) => {
59152
+ if (getDevContext()) {
59153
+ return invoke(engine, { params, governor, methodName });
59154
+ }
59155
+ else {
59156
+ try {
59157
+ return invoke(engine, { params, governor, methodName });
59020
59158
  }
59021
- else {
59022
- try {
59023
- return invoke({ params, governor, methodName });
59024
- }
59025
- catch (err) {
59026
- handleCaughtError({
59027
- engineName: 'matchUpEngine',
59028
- methodName,
59029
- params,
59030
- err,
59031
- });
59032
- }
59159
+ catch (err) {
59160
+ handleCaughtError({
59161
+ engineName: 'matchUpEngine',
59162
+ methodName,
59163
+ params,
59164
+ err,
59165
+ });
59033
59166
  }
59034
- };
59035
- });
59167
+ }
59168
+ };
59036
59169
  });
59170
+ });
59171
+ }
59172
+ function invoke(engine, { params, governor, methodName }) {
59173
+ engine.error = undefined;
59174
+ engine.success = false;
59175
+ const matchUp = params?.matchUp || getMatchUp();
59176
+ const matchUps = params?.matchUps || getMatchUps();
59177
+ const snapshot = params?.rollbackOnError && makeDeepCopy(matchUp, false, true);
59178
+ params = {
59179
+ ...params,
59180
+ matchUpId: matchUp?.matchUpId,
59181
+ matchUps,
59182
+ matchUp,
59183
+ };
59184
+ const result = governor[methodName](params);
59185
+ if (result?.error) {
59186
+ if (snapshot)
59187
+ setState(snapshot);
59188
+ return { ...result, rolledBack: !!snapshot };
59037
59189
  }
59038
- function invoke({ params, governor, methodName }) {
59039
- engine.error = undefined;
59040
- engine.success = false;
59041
- const matchUp = params?.matchUp || getMatchUp();
59042
- const matchUps = params?.matchUps || getMatchUps();
59043
- const snapshot = params?.rollbackOnError && makeDeepCopy(matchUp, false, true);
59044
- params = {
59045
- ...params,
59046
- matchUpId: matchUp?.matchUpId,
59047
- matchUps,
59048
- matchUp,
59049
- };
59050
- const result = governor[methodName](params);
59051
- if (result?.error) {
59052
- if (snapshot)
59053
- setState(snapshot);
59054
- return { ...result, rolledBack: !!snapshot };
59055
- }
59056
- const notify = result?.success && params?.delayNotify !== true && params?.doNotNotify !== true;
59057
- if (notify)
59058
- notifySubscribers();
59059
- if (notify || !result?.success || params?.doNotNotify)
59060
- deleteNotices();
59061
- return result;
59062
- }
59063
- })();
59190
+ const notify = result?.success && params?.delayNotify !== true && params?.doNotNotify !== true;
59191
+ if (notify)
59192
+ notifySubscribers();
59193
+ if (notify || !result?.success || params?.doNotNotify)
59194
+ deleteNotices();
59195
+ return result;
59196
+ }
59064
59197
 
59065
59198
  let devContextSet = false;
59066
59199
  const mocksEngine = (() => {