tods-competition-factory 1.6.17 → 1.6.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -329,7 +329,7 @@ const matchUpFormatCode = {
329
329
  };
330
330
 
331
331
  function factoryVersion() {
332
- return "1.6.17";
332
+ return "1.6.19";
333
333
  }
334
334
 
335
335
  function getObjectTieFormat(obj) {
@@ -23475,8 +23475,9 @@ function getTargetMatchUps({
23475
23475
  return { drawPositions, matchUps, targetMatchUps };
23476
23476
  }
23477
23477
 
23478
- function cleanupLineUps({
23478
+ function resetLineUps({
23479
23479
  inContextDrawMatchUps,
23480
+ inheritance = true,
23480
23481
  tournamentRecord,
23481
23482
  drawDefinition,
23482
23483
  matchUpsMap,
@@ -23484,6 +23485,8 @@ function cleanupLineUps({
23484
23485
  structure,
23485
23486
  event
23486
23487
  }) {
23488
+ if (!drawDefinition)
23489
+ return { error: MISSING_DRAW_DEFINITION };
23487
23490
  const { drawPositions, matchUps, targetMatchUps } = getTargetMatchUps({
23488
23491
  inContextDrawMatchUps,
23489
23492
  matchUpsMap,
@@ -23499,10 +23502,14 @@ function cleanupLineUps({
23499
23502
  ({ matchUpId }) => matchUpId === inContextMatchUp.matchUpId
23500
23503
  );
23501
23504
  if (matchUp?.sides?.[sideIndex]) {
23502
- delete matchUp?.sides[sideIndex].lineUp;
23505
+ if (inheritance) {
23506
+ delete matchUp.sides[sideIndex].lineUp;
23507
+ } else {
23508
+ matchUp.sides[sideIndex].lineUp = [];
23509
+ }
23503
23510
  modifyMatchUpNotice({
23504
23511
  tournamentId: tournamentRecord?.tournamentId,
23505
- context: "cleanupLineUps",
23512
+ context: "resetLineUps",
23506
23513
  eventId: event?.eventId,
23507
23514
  drawDefinition,
23508
23515
  matchUp
@@ -23622,7 +23629,7 @@ function assignDrawPosition$1({
23622
23629
  if (drawPositionIsActive) {
23623
23630
  return decorateResult({ result: { error: DRAW_POSITION_ACTIVE }, stack });
23624
23631
  }
23625
- cleanupLineUps({
23632
+ resetLineUps({
23626
23633
  assignments: [positionAssignment],
23627
23634
  inContextDrawMatchUps,
23628
23635
  tournamentRecord,
@@ -44527,7 +44534,7 @@ function eliminationParticipantSwap({
44527
44534
  structure.positionAssignments = structure.positionAssignments.map(
44528
44535
  (assignment) => newAssignments[assignment.drawPosition] || assignment
44529
44536
  );
44530
- cleanupLineUps({
44537
+ resetLineUps({
44531
44538
  inContextDrawMatchUps,
44532
44539
  tournamentRecord,
44533
44540
  drawDefinition,
@@ -44559,7 +44566,7 @@ function roundRobinSwap({
44559
44566
  return { ...SUCCESS };
44560
44567
  if (assignments.filter(({ qualifier }) => qualifier).length === 2)
44561
44568
  return { ...SUCCESS };
44562
- cleanupLineUps({
44569
+ resetLineUps({
44563
44570
  inContextDrawMatchUps,
44564
44571
  tournamentRecord,
44565
44572
  drawDefinition,
@@ -44590,6 +44597,40 @@ function roundRobinSwap({
44590
44597
  return { ...SUCCESS };
44591
44598
  }
44592
44599
 
44600
+ function resetMatchUpLineUps$1({
44601
+ tournamentRecord,
44602
+ drawDefinition,
44603
+ inheritance,
44604
+ matchUpId,
44605
+ event
44606
+ }) {
44607
+ if (!drawDefinition)
44608
+ return { error: MISSING_DRAW_DEFINITION };
44609
+ const matchUp = findMatchUp$1({
44610
+ drawDefinition,
44611
+ matchUpId
44612
+ })?.matchUp;
44613
+ if (!matchUp?.tieMatchUps)
44614
+ return { error: INVALID_MATCHUP };
44615
+ let modificationsCount = 0;
44616
+ (matchUp.sides || []).forEach((side) => {
44617
+ modificationsCount += 1;
44618
+ if (inheritance) {
44619
+ delete side.lineUp;
44620
+ } else {
44621
+ side.lineUp = [];
44622
+ }
44623
+ modifyMatchUpNotice({
44624
+ tournamentId: tournamentRecord?.tournamentId,
44625
+ context: "resetLineUps",
44626
+ eventId: event?.eventId,
44627
+ drawDefinition,
44628
+ matchUp
44629
+ });
44630
+ });
44631
+ return { ...SUCCESS, modificationsCount };
44632
+ }
44633
+
44593
44634
  function setSubOrder({
44594
44635
  tournamentRecord,
44595
44636
  drawDefinition,
@@ -44656,6 +44697,7 @@ const positionGovernor = {
44656
44697
  swapDrawPositionAssignments: swapDrawPositionAssignments$1,
44657
44698
  alternateDrawPositionAssignment: alternateDrawPositionAssignment$1,
44658
44699
  resolveDrawPositions,
44700
+ resetMatchUpLineUps: resetMatchUpLineUps$1,
44659
44701
  // probably not part of drawEngine final
44660
44702
  initializeStructureSeedAssignments,
44661
44703
  getNextSeedBlock
@@ -51282,362 +51324,1500 @@ const publishingGovernor = {
51282
51324
  publishOrderOfPlay: publishOrderOfPlay$1
51283
51325
  };
51284
51326
 
51285
- function convertPointEight({ tournament }) {
51286
- if (!tournament)
51287
- return { error: MISSING_TOURNAMENT_RECORD };
51288
- const {
51289
- providerTournamentID: tournamentId,
51290
- hostCountryCode,
51291
- tournamentLevel,
51292
- totalPrizeMoney,
51293
- tournamentName,
51294
- extensions,
51295
- startDate,
51296
- endDate
51297
- } = tournament;
51298
- const tournamentRecord = newTournamentRecord({
51299
- hostCountryCode,
51300
- tournamentLevel,
51301
- totalPrizeMoney,
51302
- tournamentName,
51303
- tournamentId,
51304
- extensions,
51305
- startDate,
51306
- endDate
51307
- });
51308
- tournamentRecord.events = [];
51309
- for (const legacyEvent of tournament.events || []) {
51310
- const {
51311
- extensions: extensions2,
51312
- ageCategory,
51313
- discipline,
51314
- eventType,
51315
- eventId,
51316
- gender,
51317
- stages
51318
- } = legacyEvent;
51319
- const event = {
51320
- drawDefinitions: deriveDraws(stages),
51321
- category: { ageCategory },
51322
- gender: ["M", MALE].includes(gender) && MALE || ["F", FEMALE].includes(gender) && FEMALE || void 0,
51323
- eventType: ["D", DOUBLES].includes(eventType) && DOUBLES || ["T", TEAM$1].includes(eventType) ? TEAM$1 : SINGLES,
51324
- extensions: extensions2,
51325
- discipline,
51326
- eventId
51327
+ function removeCollectionAssignments({
51328
+ collectionPosition,
51329
+ teamParticipantId,
51330
+ dualMatchUpSide,
51331
+ drawDefinition,
51332
+ participantIds,
51333
+ collectionId
51334
+ }) {
51335
+ if (!collectionId || !collectionPosition || !Array.isArray(participantIds))
51336
+ return {
51337
+ modifiedLineUp: dualMatchUpSide?.lineUp || [],
51338
+ error: INVALID_VALUES
51327
51339
  };
51328
- tournamentRecord.events.push(event);
51329
- }
51330
- return { ...SUCCESS, tournamentRecord };
51331
- }
51332
- function deriveDraws(stages) {
51333
- const drawDefinitions = [];
51334
- for (const legacyStage of stages || []) {
51335
- const { stageType } = legacyStage;
51336
- const stage = ["M", MAIN].includes(stageType) && MAIN || ["Q", QUALIFYING].includes(stageType) && QUALIFYING || ["C", CONSOLATION].includes(stageType) && CONSOLATION || ["P", PLAY_OFF].includes(stageType) && PLAY_OFF || void 0;
51337
- for (const draw of legacyStage.draws || []) {
51338
- const { drawId, drawSize, matchUps } = draw;
51339
- const drawDefinition = { stage, drawId, drawSize };
51340
- drawDefinitions.push(drawDefinition);
51341
- console.log(
51342
- matchUps.map(({ roundNumber, roundPosition }) => ({
51343
- roundNumber,
51344
- roundPosition
51345
- })),
51346
- { draw, drawDefinition }
51347
- );
51340
+ const lineUp = dualMatchUpSide?.lineUp || getTeamLineUp({
51341
+ participantId: teamParticipantId,
51342
+ drawDefinition
51343
+ })?.lineUp;
51344
+ const previousParticipantIds = [];
51345
+ const assignmentsRemoved = [];
51346
+ const modifiedLineUp = lineUp?.map((teamCompetitor) => {
51347
+ if (!participantIds.includes(teamCompetitor.participantId)) {
51348
+ return teamCompetitor;
51348
51349
  }
51349
- }
51350
- return drawDefinitions;
51351
- }
51352
-
51353
- const ABANDONED = "ABANDONED";
51354
- const ACTIVE = "ACTIVE";
51355
- const CANCELLED = "CANCELLED";
51356
- const COMPLETED = "COMPLETED";
51357
- const IN_PROGRESS = "IN_PROGRESS";
51358
- const tournamentConstants = {
51359
- ABANDONED,
51360
- ACTIVE,
51361
- CANCELLED,
51362
- COMPLETED,
51363
- IN_PROGRESS
51364
- };
51365
-
51366
- function setTournamentStatus({ tournamentRecord, status }) {
51367
- if (!tournamentRecord)
51368
- return { error: MISSING_TOURNAMENT_RECORD };
51369
- if (status && !Object.keys(tournamentConstants).includes(status))
51370
- return { error: INVALID_VALUES, info: "Unknown status" };
51371
- tournamentRecord.tournamentStatus = status;
51372
- return { ...SUCCESS };
51373
- }
51374
-
51375
- function analyzeDraws({ tournamentRecord }) {
51376
- if (!tournamentRecord)
51377
- return { error: MISSING_TOURNAMENT_RECORD };
51378
- const drawsAnalysis = {
51379
- positionsNoOutcomes: [],
51380
- // all positions assigned and no outcomes
51381
- canBePruned: [],
51382
- // partially assigned positions with outcomes => drawSizes can be reduced
51383
- matchPlay: [],
51384
- // only first round has active matchUps; some unassigned positions
51385
- inactive: [],
51386
- drawAnalysis: {}
51387
- };
51388
- const eventsMap = {};
51389
- const eventDraws = tournamentRecord.events?.map((event) => {
51390
- const eventId = event.eventId;
51391
- eventsMap[eventId] = event;
51392
- return (event?.drawDefinitions || []).map((drawDefinition) => ({
51393
- drawDefinition,
51394
- eventId
51395
- }));
51396
- }).flat().filter(Boolean);
51397
- eventDraws.forEach(({ drawDefinition, eventId }) => {
51398
- let positionsAssignedCount = 0;
51399
- let matchUpsWithWinningSideCount = 0;
51400
- let matchUpsNoOutcomeCount = 0;
51401
- const { allStructuresLinked } = getStructureGroups({ drawDefinition });
51402
- const event = eventsMap[eventId];
51403
- const structures = drawDefinition?.structures || [];
51404
- const structuresData = structures.map((structure) => {
51405
- const { stage, stageSequence, structureId } = structure;
51406
- const orderNumber = stageOrder$1[stage];
51407
- const { inContextStructureMatchUps } = getStructureDrawPositionProfiles({
51408
- drawDefinition,
51409
- structure,
51410
- event
51411
- });
51412
- const matchUpsWithWinningSide = inContextStructureMatchUps?.filter(
51413
- ({ winningSide }) => winningSide
51414
- );
51415
- const winningSideCount = matchUpsWithWinningSide.filter(Boolean).length || 0;
51416
- matchUpsWithWinningSideCount += winningSideCount;
51417
- matchUpsNoOutcomeCount += inContextStructureMatchUps.length - matchUpsWithWinningSideCount;
51418
- const maxWinningSideFirstRoundPosition = Math.max(
51419
- matchUpsWithWinningSide.filter(({ roundNumber }) => roundNumber === 1).map(({ roundPosition }) => roundPosition)
51420
- );
51421
- const { positionAssignments } = getPositionAssignments$1({ structure });
51422
- const positionsAssigned = positionAssignments?.filter(
51423
- ({ participantId }) => participantId
51424
- );
51425
- positionsAssignedCount += positionsAssigned?.length || 0;
51426
- const unassignedPositionsCount = (positionAssignments?.length || 0) - (positionsAssigned?.length || 0);
51427
- const { roundMatchUps, roundProfile, roundNumbers, maxMatchUpsCount } = getRoundMatchUps$1({ matchUps: inContextStructureMatchUps });
51428
- const activeRounds = roundProfile && Object.keys(roundProfile).filter((roundNumber) => !roundProfile[roundNumber].inactiveRound).map((roundNumber) => parseInt(roundNumber));
51429
- const inactiveRounds = roundProfile && Object.keys(roundProfile).filter((roundNumber) => roundProfile[roundNumber].inactiveRound).map((roundNumber) => parseInt(roundNumber));
51430
- const inactiveStructure = roundProfile && Object.values(roundProfile).every((profile) => profile.inactiveRound);
51431
- return {
51432
- positionsAssignedCount: positionsAssigned?.length || 0,
51433
- maxWinningSideFirstRoundPosition,
51434
- unassignedPositionsCount,
51435
- inactiveStructure,
51436
- maxMatchUpsCount,
51437
- inactiveRounds,
51438
- roundMatchUps,
51439
- activeRounds,
51440
- roundNumbers,
51441
- roundProfile,
51442
- structureId,
51443
- stageSequence,
51444
- orderNumber,
51445
- stage
51446
- };
51447
- });
51448
- const mainStructure = structuresData.find(
51449
- (data) => data.orderNumber === 2 && data.stageSequence === 1
51450
- );
51451
- const activeStructuresCount = structuresData.filter(
51452
- ({ inactiveStructure }) => !inactiveStructure
51453
- ).length;
51454
- const { links } = getStructureLinks({
51455
- drawDefinition,
51456
- structureId: mainStructure.structureId
51350
+ const collectionAssignments = teamCompetitor.collectionAssignments?.filter((assignment) => {
51351
+ const target = assignment.collectionId === collectionId && assignment.collectionPosition === collectionPosition;
51352
+ if (target) {
51353
+ if (assignment.previousParticipantId) {
51354
+ previousParticipantIds.push(assignment.previousParticipantId);
51355
+ }
51356
+ assignmentsRemoved.push({
51357
+ participantId: teamCompetitor.participantId,
51358
+ ...assignment
51359
+ });
51360
+ }
51361
+ return !target;
51457
51362
  });
51458
- const isMatchPlay = ensureInt(mainStructure.activeRounds[0]) === 1 && mainStructure.activeRounds.length === 1 && activeStructuresCount === 1;
51459
- const inactiveDraw = structuresData?.every(
51460
- ({ inactiveStructure }) => inactiveStructure
51461
- );
51462
- const canBePruned = !links.length && mainStructure.activeRounds.length && (mainStructure.roundProfile[1].inactiveCount || mainStructure.inactiveRounds.length);
51463
- const drawId = drawDefinition.drawId;
51464
- if (positionsAssignedCount && !matchUpsWithWinningSideCount)
51465
- drawsAnalysis.positionsNoOutcomes.push(drawId);
51466
- if (inactiveDraw)
51467
- drawsAnalysis.inactive.push(drawId);
51468
- if (isMatchPlay)
51469
- drawsAnalysis.matchPlay.push(drawId);
51470
- if (canBePruned)
51471
- drawsAnalysis.canBePruned.push(drawId);
51472
- const drawAnalysis = {
51473
- matchUpsWithWinningSideCount,
51474
- matchUpsNoOutcomeCount,
51475
- positionsAssignedCount,
51476
- allStructuresLinked,
51477
- structuresData,
51478
- inactiveDraw,
51479
- isMatchPlay,
51480
- drawId
51363
+ return {
51364
+ participantId: teamCompetitor.participantId,
51365
+ collectionAssignments
51481
51366
  };
51482
- drawsAnalysis.drawAnalysis[drawId] = drawAnalysis;
51483
- });
51484
- return { ...SUCCESS, drawsAnalysis };
51485
- }
51486
-
51487
- function checkIsDual(tournamentRecord) {
51488
- const teamParticipants = tournamentRecord.participants?.filter(
51489
- ({ participantType }) => participantType === TEAM
51490
- );
51491
- const twoTeams = teamParticipants?.length === 2;
51492
- const event = tournamentRecord.events?.length === 1 && tournamentRecord.events[0];
51493
- const drawDefinition = event?.drawDefinitions?.length === 1 && event.drawDefinitions[0];
51494
- const structure = drawDefinition?.structures?.length === 1 && drawDefinition.structures[0];
51495
- const twoDrawPositions = structure?.positionAssignments?.length === 2;
51496
- return !!(event.tieFormat && twoTeams && twoDrawPositions);
51497
- }
51498
-
51499
- function analyzeTournament({ tournamentRecord }) {
51500
- if (!tournamentRecord)
51501
- return { error: MISSING_TOURNAMENT_RECORD };
51502
- const { drawsAnalysis } = analyzeDraws({ tournamentRecord });
51503
- const analysis = {
51504
- isDual: checkIsDual(tournamentRecord),
51505
- drawsAnalysis
51506
- };
51507
- return { ...SUCCESS, analysis };
51367
+ }).filter(Boolean) || [];
51368
+ return { modifiedLineUp, assignmentsRemoved, previousParticipantIds };
51508
51369
  }
51509
51370
 
51510
- function setTournamentName({
51511
- tournamentRecord,
51512
- promotionalName,
51513
- tournamentName,
51514
- formalName
51515
- }) {
51516
- if (!tournamentRecord)
51517
- return { error: MISSING_TOURNAMENT_RECORD };
51518
- if (tournamentName)
51519
- tournamentRecord.tournamentName = tournamentName;
51520
- if (promotionalName)
51521
- tournamentRecord.promotionalName = promotionalName;
51522
- if (formalName)
51523
- tournamentRecord.formalName = formalName;
51524
- if (tournamentRecord.promotionalName === tournamentRecord.tournamentName) {
51525
- delete tournamentRecord.promotionalName;
51526
- }
51527
- if (tournamentRecord.formalName === tournamentRecord.tournamentName) {
51528
- delete tournamentRecord.formalName;
51371
+ function validateLineUp({ lineUp, tieFormat }) {
51372
+ const errors = [];
51373
+ if (!Array.isArray(lineUp)) {
51374
+ errors.push(mustBeAnArray("lineUp"));
51375
+ return { valid: false, errors, error: INVALID_VALUES };
51529
51376
  }
51530
- return { ...SUCCESS };
51531
- }
51532
- function setTournamentNotes({ tournamentRecord, notes }) {
51533
- if (!tournamentRecord)
51534
- return { error: MISSING_TOURNAMENT_RECORD };
51535
- return addNotes({ element: tournamentRecord, notes });
51536
- }
51537
- function setTournamentCategories({ tournamentRecord, categories }) {
51538
- if (!tournamentRecord)
51539
- return { error: MISSING_TOURNAMENT_RECORD };
51540
- categories = (categories || []).filter((category) => {
51541
- return category.categoryName && category.type;
51377
+ const validItems = lineUp.every((item) => {
51378
+ if (typeof item !== "object") {
51379
+ errors.push(`lineUp entries must be objects`);
51380
+ return false;
51381
+ }
51382
+ const { participantId, collectionAssignments } = item;
51383
+ if (!participantId) {
51384
+ errors.push("Missing participantId");
51385
+ return false;
51386
+ }
51387
+ if (typeof participantId !== "string") {
51388
+ errors.push("participantIds must be strings");
51389
+ return false;
51390
+ }
51391
+ if (!Array.isArray(collectionAssignments)) {
51392
+ errors.push(mustBeAnArray("collectionAssignments"));
51393
+ return false;
51394
+ }
51395
+ return collectionAssignments.every((collectionAssignment) => {
51396
+ if (typeof collectionAssignment !== "object") {
51397
+ errors.push("collectionAssignments must be objects");
51398
+ return false;
51399
+ }
51400
+ const { collectionPosition } = collectionAssignment;
51401
+ if (typeof collectionPosition !== "number") {
51402
+ errors.push("collectionPosition must be a number");
51403
+ return false;
51404
+ }
51405
+ return true;
51406
+ });
51542
51407
  });
51543
- tournamentRecord.tournamentCategories = categories;
51544
- return { ...SUCCESS };
51408
+ const noDuplicates = unique(lineUp.map(getParticipantId)).length === lineUp.length;
51409
+ if (!noDuplicates)
51410
+ errors.push("Duplicated participantId(s)");
51411
+ const valid = validItems && noDuplicates;
51412
+ return { valid, errors, error: errors.length ? INVALID_VALUES : void 0 };
51545
51413
  }
51546
51414
 
51547
- function updateCourtAvailability({ tournamentRecord }) {
51548
- if (!tournamentRecord)
51549
- return { error: MISSING_TOURNAMENT_RECORD };
51550
- const { startDate, endDate } = tournamentRecord;
51551
- const tournamentDates = dateRange(startDate, endDate);
51552
- const courts = [];
51553
- for (const venue of tournamentRecord.venues || []) {
51554
- if (venue?.courts?.length)
51555
- courts.push(...venue.courts);
51556
- }
51557
- for (const court of courts) {
51558
- const { startTime, endTime } = (court.dateAvailability || []).reduce(
51559
- (extents, availability) => {
51560
- const startMinutes = timeStringMinutes(extents.startTime);
51561
- const endMinutes = timeStringMinutes(extents.endTime);
51562
- if (availability.startTime && timeStringMinutes(availability.startTime) < startMinutes)
51563
- extents.startTime = availability.startTime;
51564
- if (availability.endTime && timeStringMinutes(availability.endTime) > endMinutes)
51565
- extents.endTime = availability.endTime;
51566
- return extents;
51567
- },
51568
- { startTime: "08:00", endTime: "18:00" }
51569
- );
51570
- const updatedDateAvailability = tournamentDates.map((date) => {
51571
- const existing = court.dateAvailability?.find(
51572
- (availability) => availability.date === date
51573
- );
51574
- return existing || { date, startTime, endTime };
51575
- });
51576
- court.dateAvailability = updatedDateAvailability;
51577
- }
51415
+ function updateTeamLineUp({
51416
+ drawDefinition,
51417
+ participantId,
51418
+ tieFormat,
51419
+ lineUp
51420
+ }) {
51421
+ if (typeof drawDefinition !== "object")
51422
+ return { error: MISSING_DRAW_DEFINITION };
51423
+ if (typeof participantId !== "string")
51424
+ return { error: MISSING_PARTICIPANT_ID };
51425
+ const validation = validateLineUp({ lineUp, tieFormat });
51426
+ if (!validation.valid)
51427
+ return validation;
51428
+ const { extension: existingExtension } = findExtension({
51429
+ element: drawDefinition,
51430
+ name: LINEUPS
51431
+ });
51432
+ const value = existingExtension?.value || {};
51433
+ value[participantId] = removeLineUpSubstitutions({ lineUp });
51434
+ const extension = { name: LINEUPS, value };
51435
+ addExtension$1({ element: drawDefinition, extension });
51436
+ addDrawNotice({ drawDefinition });
51578
51437
  return { ...SUCCESS };
51579
51438
  }
51580
51439
 
51581
- function setTournamentDates({
51440
+ function getTieMatchUpContext({
51582
51441
  tournamentRecord,
51583
- startDate,
51584
- endDate
51442
+ drawDefinition,
51443
+ tieMatchUpId,
51444
+ event
51585
51445
  }) {
51586
51446
  if (!tournamentRecord)
51587
51447
  return { error: MISSING_TOURNAMENT_RECORD };
51588
- if (startDate && !dateValidation.test(startDate) || endDate && !dateValidation.test(endDate))
51589
- return { error: INVALID_DATE };
51590
- if (!startDate && !endDate)
51591
- return { error: MISSING_DATE };
51592
- if (endDate && startDate && new Date(endDate) < new Date(startDate))
51593
- return { error: INVALID_VALUES };
51594
- let checkScheduling;
51595
- if (startDate && tournamentRecord.startDate && new Date(startDate) > new Date(tournamentRecord.startDate) || endDate && tournamentRecord.endDate && new Date(endDate) < new Date(tournamentRecord.endDate)) {
51596
- checkScheduling = true;
51597
- }
51598
- if (startDate)
51599
- tournamentRecord.startDate = startDate;
51600
- if (endDate)
51601
- tournamentRecord.endDate = endDate;
51602
- if (startDate && tournamentRecord.endDate && new Date(startDate) > new Date(tournamentRecord.endDate)) {
51603
- tournamentRecord.endDate = startDate;
51604
- }
51605
- if (endDate && tournamentRecord.startDate && new Date(endDate) < new Date(tournamentRecord.startDate)) {
51606
- tournamentRecord.startDate = endDate;
51607
- }
51608
- const unscheduledMatchUpIds = checkScheduling && removeInvalidScheduling({ tournamentRecord })?.unscheduledMatchUpIds;
51609
- updateCourtAvailability({ tournamentRecord });
51610
- addNotice({
51611
- topic: MODIFY_TOURNAMENT_DETAIL,
51612
- payload: { startDate, endDate }
51448
+ if (!drawDefinition)
51449
+ return { error: MISSING_DRAW_ID };
51450
+ if (!event)
51451
+ return { error: EVENT_NOT_FOUND };
51452
+ const matchUpsMap = getMatchUpsMap({ drawDefinition });
51453
+ const { matchUp: tieMatchUp } = findMatchUp$1({
51454
+ matchUpId: tieMatchUpId,
51455
+ drawDefinition,
51456
+ matchUpsMap
51613
51457
  });
51614
- return { ...SUCCESS, unscheduledMatchUpIds };
51615
- }
51616
- function setTournamentStartDate({ tournamentRecord, startDate }) {
51617
- return setTournamentDates({ tournamentRecord, startDate });
51618
- }
51619
- function setTournamentEndDate({ tournamentRecord, endDate }) {
51620
- return setTournamentDates({ tournamentRecord, endDate });
51621
- }
51622
- function removeInvalidScheduling({ tournamentRecord }) {
51623
- const matchUps = allTournamentMatchUps({ tournamentRecord }).matchUps ?? [];
51624
- const startDate = tournamentRecord.startDate && new Date(tournamentRecord.startDate);
51625
- const endDate = tournamentRecord.endDate && new Date(tournamentRecord.endDate);
51626
- const invalidScheduledDates = [];
51627
- const invalidSchedulingMatchUpIds = [];
51628
- for (const matchUp of matchUps) {
51629
- const { schedule, matchUpId } = matchUp;
51630
- if (!schedule)
51631
- continue;
51632
- if (schedule.scheduledDate) {
51633
- const scheduledDate = new Date(schedule.scheduledDate);
51634
- if (startDate && scheduledDate < startDate || endDate && scheduledDate > endDate) {
51635
- invalidSchedulingMatchUpIds.push(matchUpId);
51636
- if (!invalidScheduledDates.includes(schedule.scheduledDate))
51637
- invalidScheduledDates.push(schedule.scheduledDate);
51638
- }
51458
+ if (!tieMatchUp)
51459
+ return { error: MATCHUP_NOT_FOUND };
51460
+ const { matchUp: inContextTieMatchUp, structure } = findMatchUp$1({
51461
+ tournamentParticipants: tournamentRecord.participants,
51462
+ matchUpId: tieMatchUpId,
51463
+ inContext: true,
51464
+ drawDefinition,
51465
+ matchUpsMap,
51466
+ event
51467
+ });
51468
+ if (!inContextTieMatchUp)
51469
+ return { error: MATCHUP_NOT_FOUND };
51470
+ const {
51471
+ collectionPosition,
51472
+ drawPositions,
51473
+ collectionId,
51474
+ matchUpTieId,
51475
+ matchUpType
51476
+ } = inContextTieMatchUp;
51477
+ if (matchUpType && ![SINGLES$1, DOUBLES$1].includes(matchUpType))
51478
+ return { error: INVALID_MATCHUP };
51479
+ const { positionAssignments } = getPositionAssignments$1({ structure });
51480
+ const relevantAssignments = positionAssignments?.filter(
51481
+ (assignment) => drawPositions?.includes(assignment.drawPosition)
51482
+ );
51483
+ const participantIds = relevantAssignments?.map(
51484
+ extractAttributes("participantId")
51485
+ );
51486
+ const { tournamentParticipants: teamParticipants } = getTournamentParticipants({
51487
+ tournamentRecord,
51488
+ participantFilters: {
51489
+ participantTypes: [TEAM],
51490
+ participantIds
51639
51491
  }
51640
- }
51492
+ });
51493
+ const { matchUp: dualMatchUp } = findMatchUp$1({
51494
+ matchUpId: matchUpTieId,
51495
+ drawDefinition,
51496
+ matchUpsMap
51497
+ });
51498
+ const { matchUp: inContextDualMatchUp } = findMatchUp$1({
51499
+ matchUpId: matchUpTieId,
51500
+ inContext: true,
51501
+ drawDefinition,
51502
+ matchUpsMap
51503
+ });
51504
+ const tieFormat = resolveTieFormat({
51505
+ matchUp: dualMatchUp,
51506
+ drawDefinition,
51507
+ structure,
51508
+ event
51509
+ })?.tieFormat;
51510
+ return {
51511
+ inContextDualMatchUp,
51512
+ inContextTieMatchUp,
51513
+ relevantAssignments,
51514
+ collectionPosition,
51515
+ teamParticipants,
51516
+ collectionId,
51517
+ matchUpType,
51518
+ dualMatchUp,
51519
+ tieMatchUp,
51520
+ tieFormat,
51521
+ structure,
51522
+ ...SUCCESS
51523
+ };
51524
+ }
51525
+
51526
+ function assignTieMatchUpParticipantId(params) {
51527
+ const matchUpContext = getTieMatchUpContext(params);
51528
+ if (matchUpContext.error)
51529
+ return matchUpContext;
51530
+ const stack = "assignTieMatchUpParticipantId";
51531
+ let teamParticipantId = params.teamParticipantId;
51532
+ const { tournamentRecord, drawDefinition, participantId, event } = params;
51533
+ if (!participantId) {
51534
+ return decorateResult({ result: { error: MISSING_PARTICIPANT_ID }, stack });
51535
+ }
51536
+ if (params.sideNumber && ![1, 2].includes(params.sideNumber)) {
51537
+ return decorateResult({ result: { error: INVALID_SIDE_NUMBER }, stack });
51538
+ }
51539
+ const {
51540
+ inContextDualMatchUp,
51541
+ inContextTieMatchUp,
51542
+ relevantAssignments,
51543
+ collectionPosition,
51544
+ teamParticipants,
51545
+ collectionId,
51546
+ matchUpType,
51547
+ dualMatchUp,
51548
+ tieFormat
51549
+ } = matchUpContext;
51550
+ const allTieIndividualParticipantIds = inContextTieMatchUp?.sides?.flatMap(
51551
+ (side) => side.participant?.individualParticipantIds || side.participant?.participantId || []
51552
+ );
51553
+ if (allTieIndividualParticipantIds?.includes(participantId)) {
51554
+ return decorateResult({ result: { ...SUCCESS }, stack });
51555
+ }
51556
+ teamParticipantId = teamParticipantId || params.sideNumber && inContextDualMatchUp?.sides?.find(
51557
+ (side) => side.sideNumber === params.sideNumber
51558
+ )?.participantId;
51559
+ const {
51560
+ tournamentParticipants: [participantToAssign]
51561
+ } = getTournamentParticipants({
51562
+ tournamentRecord,
51563
+ participantFilters: {
51564
+ participantIds: [participantId]
51565
+ }
51566
+ });
51567
+ if (!participantToAssign) {
51568
+ return decorateResult({ result: { error: PARTICIPANT_NOT_FOUND }, stack });
51569
+ }
51570
+ const { appliedPolicies } = getAppliedPolicies({
51571
+ tournamentRecord,
51572
+ drawDefinition,
51573
+ event
51574
+ });
51575
+ const matchUpActionsPolicy = params.policyDefinitions?.[POLICY_TYPE_MATCHUP_ACTIONS] || appliedPolicies?.[POLICY_TYPE_MATCHUP_ACTIONS] || POLICY_MATCHUP_ACTIONS_DEFAULT[POLICY_TYPE_MATCHUP_ACTIONS];
51576
+ if (matchUpActionsPolicy?.participants?.enforceGender && [MALE, FEMALE].includes(inContextTieMatchUp?.gender) && inContextTieMatchUp?.gender !== participantToAssign.person?.sex) {
51577
+ return { error: INVALID_PARTICIPANT, info: "Gender mismatch" };
51578
+ }
51579
+ const { individualParticipantIds, participantType } = participantToAssign;
51580
+ if (matchUpType === SINGLES$1 && participantType !== INDIVIDUAL) {
51581
+ return { error: INVALID_PARTICIPANT_TYPE };
51582
+ }
51583
+ const relevantParticipantIds = participantType === INDIVIDUAL ? [participantId] : individualParticipantIds;
51584
+ const participantTeam = teamParticipantId && teamParticipants?.find(
51585
+ ({ participantId: participantId2 }) => participantId2 === teamParticipantId
51586
+ ) || teamParticipants?.find(
51587
+ ({ individualParticipantIds: individualParticipantIds2 }) => overlap(relevantParticipantIds, individualParticipantIds2)
51588
+ );
51589
+ if (!participantTeam) {
51590
+ return { error: TEAM_NOT_FOUND };
51591
+ }
51592
+ if (!teamParticipantId)
51593
+ teamParticipantId = participantTeam.participantId;
51594
+ if (!teamParticipantId)
51595
+ return { error: PARTICIPANT_NOT_FOUND };
51596
+ const teamAssignment = relevantAssignments?.find(
51597
+ (assignment) => assignment.participantId === participantTeam?.participantId
51598
+ );
51599
+ const teamDrawPosition = teamAssignment?.drawPosition;
51600
+ const teamSide = inContextTieMatchUp?.sides?.find(
51601
+ (side) => side.drawPosition === teamDrawPosition
51602
+ );
51603
+ const sideNumber = params.sideNumber || teamSide?.sideNumber;
51604
+ if (!tieFormat) {
51605
+ return { error: MISSING_TIE_FORMAT };
51606
+ }
51607
+ const collectionDefinition = tieFormat.collectionDefinitions?.find(
51608
+ (collectionDefinition2) => collectionDefinition2.collectionId === collectionId
51609
+ );
51610
+ if (!collectionDefinition)
51611
+ return { error: MISSING_COLLECTION_DEFINITION };
51612
+ if (!dualMatchUp?.sides?.length) {
51613
+ const { extension } = findExtension$2({
51614
+ element: drawDefinition,
51615
+ name: LINEUPS
51616
+ });
51617
+ const lineUps = makeDeepCopy(extension?.value || {}, false, true);
51618
+ const extractSideDetail = ({
51619
+ displaySideNumber,
51620
+ drawPosition,
51621
+ sideNumber: sideNumber2
51622
+ }) => ({ drawPosition, sideNumber: sideNumber2, displaySideNumber });
51623
+ if (dualMatchUp) {
51624
+ dualMatchUp.sides = inContextDualMatchUp?.sides?.map((side) => {
51625
+ const participantId2 = side.participantId;
51626
+ return {
51627
+ ...extractSideDetail(side),
51628
+ lineUp: participantId2 && lineUps[participantId2] || []
51629
+ };
51630
+ });
51631
+ }
51632
+ }
51633
+ const dualMatchUpSide = dualMatchUp?.sides?.find(
51634
+ (side) => side.sideNumber === sideNumber
51635
+ );
51636
+ const tieMatchUpSide = inContextTieMatchUp?.sides?.find(
51637
+ (side) => side.sideNumber === sideNumber
51638
+ );
51639
+ const lineUp = dualMatchUpSide?.lineUp || getTeamLineUp({
51640
+ participantId: teamParticipantId,
51641
+ drawDefinition
51642
+ })?.lineUp;
51643
+ const targetAssignments = lineUp?.filter(
51644
+ (participantAssignment) => participantAssignment.collectionAssignments?.find(
51645
+ (assignment) => assignment.collectionPosition === collectionPosition && assignment.collectionId === collectionId && !assignment.previousParticipantId
51646
+ )
51647
+ );
51648
+ const assignedParticipantIds = targetAssignments?.map(
51649
+ (assignment) => assignment?.participantId
51650
+ );
51651
+ const participantIds = assignedParticipantIds?.length > 1 && assignedParticipantIds || (participantType === PAIR ? participantToAssign.individualParticipantIds : [participantId]);
51652
+ const removeResult = removeCollectionAssignments({
51653
+ collectionPosition,
51654
+ teamParticipantId,
51655
+ dualMatchUpSide,
51656
+ drawDefinition,
51657
+ participantIds,
51658
+ collectionId
51659
+ });
51660
+ if (removeResult.error)
51661
+ return decorateResult({ result: removeResult, stack });
51662
+ const { modifiedLineUp } = removeResult;
51663
+ let deleteParticipantId;
51664
+ if (matchUpType === DOUBLES$1) {
51665
+ if (participantType !== PAIR) {
51666
+ let result = updateLineUp({
51667
+ collectionPosition,
51668
+ teamParticipantId,
51669
+ drawDefinition,
51670
+ modifiedLineUp,
51671
+ participantId,
51672
+ collectionId,
51673
+ tieFormat
51674
+ });
51675
+ if (result?.error)
51676
+ return decorateResult({ result, stack });
51677
+ result = addParticipantId2Pair({
51678
+ side: tieMatchUpSide
51679
+ });
51680
+ if (result.error)
51681
+ return result;
51682
+ deleteParticipantId = result.deleteParticipantId;
51683
+ if (dualMatchUpSide)
51684
+ dualMatchUpSide.lineUp = modifiedLineUp;
51685
+ if (dualMatchUp) {
51686
+ modifyMatchUpNotice({
51687
+ tournamentId: tournamentRecord?.tournamentId,
51688
+ matchUp: dualMatchUp,
51689
+ context: stack,
51690
+ drawDefinition
51691
+ });
51692
+ }
51693
+ } else if (participantType === PAIR) {
51694
+ for (const participantId2 of participantIds) {
51695
+ updateLineUp({
51696
+ collectionPosition,
51697
+ teamParticipantId,
51698
+ drawDefinition,
51699
+ modifiedLineUp,
51700
+ participantId: participantId2,
51701
+ collectionId,
51702
+ tieFormat
51703
+ });
51704
+ }
51705
+ }
51706
+ } else {
51707
+ const result = updateLineUp({
51708
+ collectionPosition,
51709
+ teamParticipantId,
51710
+ drawDefinition,
51711
+ modifiedLineUp,
51712
+ participantId,
51713
+ collectionId,
51714
+ tieFormat
51715
+ });
51716
+ if (result?.error)
51717
+ return result;
51718
+ }
51719
+ if (dualMatchUpSide)
51720
+ dualMatchUpSide.lineUp = modifiedLineUp;
51721
+ if (dualMatchUp)
51722
+ modifyMatchUpNotice({
51723
+ tournamentId: tournamentRecord?.tournamentId,
51724
+ matchUp: dualMatchUp,
51725
+ context: stack,
51726
+ drawDefinition
51727
+ });
51728
+ if (deleteParticipantId) {
51729
+ const { error } = deleteParticipants({
51730
+ participantIds: [deleteParticipantId],
51731
+ tournamentRecord
51732
+ });
51733
+ if (error)
51734
+ console.log("cleanup");
51735
+ }
51736
+ return { ...SUCCESS, modifiedLineUp };
51737
+ function addParticipantId2Pair({ side }) {
51738
+ let deleteParticipantId2;
51739
+ if (!side.participant) {
51740
+ const newPairParticipant = {
51741
+ individualParticipantIds: [participantId],
51742
+ participantRole: COMPETITOR,
51743
+ participantType: PAIR
51744
+ };
51745
+ const result = addParticipant$1({
51746
+ participant: newPairParticipant,
51747
+ pairOverride: true,
51748
+ tournamentRecord
51749
+ });
51750
+ if (result.error)
51751
+ return result;
51752
+ } else {
51753
+ const individualParticipantIds2 = side.participant.individualParticipantIds || [];
51754
+ const sideParticipantsCount = individualParticipantIds2.filter(Boolean).length;
51755
+ if (sideParticipantsCount === 1) {
51756
+ const { participant } = getPairedParticipant({
51757
+ participantIds: individualParticipantIds2,
51758
+ tournamentRecord
51759
+ });
51760
+ individualParticipantIds2.push(participantId);
51761
+ const { participant: existingParticipant } = getPairedParticipant({
51762
+ participantIds: individualParticipantIds2,
51763
+ tournamentRecord
51764
+ });
51765
+ if (!existingParticipant && participant) {
51766
+ participant.individualParticipantIds = individualParticipantIds2;
51767
+ const result = modifyParticipant({
51768
+ pairOverride: true,
51769
+ tournamentRecord,
51770
+ participant
51771
+ });
51772
+ if (result.error)
51773
+ return result;
51774
+ } else {
51775
+ deleteParticipantId2 = participant?.participantId;
51776
+ }
51777
+ }
51778
+ }
51779
+ return { ...SUCCESS, deleteParticipantId: deleteParticipantId2 };
51780
+ }
51781
+ }
51782
+ function updateLineUp({
51783
+ collectionPosition,
51784
+ teamParticipantId,
51785
+ drawDefinition,
51786
+ modifiedLineUp,
51787
+ participantId,
51788
+ collectionId,
51789
+ tieFormat
51790
+ }) {
51791
+ const templateTeamLineUp = getTeamLineUp({
51792
+ participantId: teamParticipantId,
51793
+ drawDefinition
51794
+ })?.lineUp;
51795
+ const participantCompetitiorProfile = (modifiedLineUp || templateTeamLineUp)?.find((teamCompetitor) => teamCompetitor?.participantId === participantId);
51796
+ const newAssignment = { collectionId, collectionPosition };
51797
+ if (participantCompetitiorProfile) {
51798
+ participantCompetitiorProfile.collectionAssignments.push(newAssignment);
51799
+ } else {
51800
+ const teamCompetitor = {
51801
+ collectionAssignments: [newAssignment],
51802
+ participantId
51803
+ };
51804
+ modifiedLineUp.push(teamCompetitor);
51805
+ }
51806
+ return updateTeamLineUp({
51807
+ participantId: teamParticipantId,
51808
+ lineUp: modifiedLineUp,
51809
+ drawDefinition,
51810
+ tieFormat
51811
+ });
51812
+ }
51813
+
51814
+ const ASC = "ASC";
51815
+ const ASCENDING = "ASC";
51816
+ const DESC = "DESC";
51817
+ const DESCENDING = "DESC";
51818
+ const sortingConstants = { ASC, ASCENDING, DESC, DESCENDING };
51819
+
51820
+ function generateLineUps(params) {
51821
+ let { tieFormat } = params;
51822
+ const {
51823
+ useDefaultEventRanking,
51824
+ tournamentRecord,
51825
+ drawDefinition,
51826
+ scaleAccessor,
51827
+ // e.g. { scaleType: 'RANKINGS', scaleName: 'U18', accessor: 'wtnRating', sortOrder: 'ASC' }
51828
+ singlesOnly,
51829
+ // use singles scale for doubles events
51830
+ attach,
51831
+ // boolean - when true attach LINEUPS extension to drawDefinition and add new PAIR participants (where necessary)
51832
+ event
51833
+ } = params;
51834
+ if (event?.eventType !== TEAM_EVENT)
51835
+ return { error: INVALID_EVENT_TYPE };
51836
+ if (!tournamentRecord)
51837
+ return { error: MISSING_TOURNAMENT_RECORD };
51838
+ if (!tieFormat && !drawDefinition)
51839
+ return { error: DRAW_DEFINITION_NOT_FOUND };
51840
+ tieFormat = tieFormat || resolveTieFormat({ drawDefinition, event })?.tieFormat;
51841
+ if (validateTieFormat({ tieFormat }).error)
51842
+ return { error: INVALID_TIE_FORMAT };
51843
+ if (typeof scaleAccessor !== "object" && !useDefaultEventRanking)
51844
+ return { error: INVALID_VALUES, context: { scaleAccessor } };
51845
+ const lineUps = {};
51846
+ const targetEntries = (drawDefinition?.entries || event.entries).filter(
51847
+ (entry) => entry?.entryStatus === DIRECT_ACCEPTANCE
51848
+ );
51849
+ const participantIds = targetEntries.map(getParticipantId);
51850
+ const { participants = [] } = getParticipants$1({
51851
+ withIndividualParticipants: true,
51852
+ withScaleValues: true,
51853
+ tournamentRecord
51854
+ });
51855
+ const teamParticipants = participants.filter(
51856
+ ({ participantId }) => participantIds.includes(participantId)
51857
+ );
51858
+ const formatScaleType = (type) => type === RANKING$1 ? "rankings" : "ratings";
51859
+ const defaultScaleName = event?.category?.categoryName || event?.category?.ageCategoryCode;
51860
+ const {
51861
+ scaleName = defaultScaleName,
51862
+ scaleType = RANKING$1,
51863
+ sortOrder,
51864
+ accessor
51865
+ } = scaleAccessor || {};
51866
+ const formattedScaleType = formatScaleType(scaleType);
51867
+ const getScaleValue = (individualParticipant, matchUpType) => {
51868
+ let matchUpTypeScales = individualParticipant[formattedScaleType]?.[matchUpType];
51869
+ if (!matchUpTypeScales && useDefaultEventRanking) {
51870
+ matchUpTypeScales = individualParticipant[formattedScaleType]?.[SINGLES_MATCHUP];
51871
+ }
51872
+ if (Array.isArray(matchUpTypeScales)) {
51873
+ const scaleValue = matchUpTypeScales.find(
51874
+ (scale) => scale.scaleName === scaleName
51875
+ )?.scaleValue;
51876
+ if (isNumeric(scaleValue)) {
51877
+ return scaleValue;
51878
+ } else if (accessor && typeof scaleValue === "object")
51879
+ return scaleValue[accessor];
51880
+ }
51881
+ return 0;
51882
+ };
51883
+ const sortMethod = (a, b, matchUpType) => {
51884
+ const x = sortOrder === DESCENDING ? b : a;
51885
+ const y = sortOrder === DESCENDING ? a : b;
51886
+ return getScaleValue(x, matchUpType) - getScaleValue(y, matchUpType);
51887
+ };
51888
+ const singlesScaleSort = (a, b) => sortMethod(a, b, SINGLES_MATCHUP);
51889
+ const doublesScaleSort = (a, b) => sortMethod(a, b, DOUBLES_MATCHUP);
51890
+ const participantIdPairs = [];
51891
+ const collectionDefinitions = tieFormat.collectionDefinitions || [];
51892
+ for (const teamParticipant of teamParticipants) {
51893
+ const singlesSort = teamParticipant.individualParticipants.sort(singlesScaleSort);
51894
+ const doublesSort = singlesOnly ? singlesSort : teamParticipant.individualParticipants.sort(doublesScaleSort);
51895
+ const participantAssignments = {};
51896
+ for (const collectionDefinition of collectionDefinitions) {
51897
+ const collectionParticipantIds = [];
51898
+ const { collectionId, matchUpCount, matchUpType, gender } = collectionDefinition;
51899
+ const singlesMatchUp = matchUpType === SINGLES_MATCHUP;
51900
+ generateRange(0, matchUpCount).forEach((i) => {
51901
+ const typeSort = singlesMatchUp ? singlesSort : doublesSort;
51902
+ const collectionPosition = i + 1;
51903
+ const participantIds2 = [];
51904
+ generateRange(0, singlesMatchUp ? 1 : 2).forEach((i2) => {
51905
+ const nextParticipantId = typeSort.find((participant) => {
51906
+ const targetGender = [MALE, FEMALE].includes(gender) && gender || gender === MIXED && [MALE, FEMALE][i2];
51907
+ return (!targetGender || targetGender === participant.person.sex) && !collectionParticipantIds.includes(participant.participantId);
51908
+ }).participantId;
51909
+ if (nextParticipantId) {
51910
+ participantIds2.push(nextParticipantId);
51911
+ collectionParticipantIds.push(nextParticipantId);
51912
+ if (!participantAssignments[nextParticipantId])
51913
+ participantAssignments[nextParticipantId] = [];
51914
+ participantAssignments[nextParticipantId].push({
51915
+ collectionPosition,
51916
+ collectionId
51917
+ });
51918
+ }
51919
+ });
51920
+ if (!singlesMatchUp)
51921
+ participantIdPairs.push(participantIds2);
51922
+ });
51923
+ }
51924
+ const lineUp = Object.keys(participantAssignments).map((participantId) => ({
51925
+ collectionAssignments: participantAssignments[participantId],
51926
+ participantId
51927
+ }));
51928
+ lineUps[teamParticipant.participantId] = lineUp;
51929
+ }
51930
+ const participantsToAdd = [];
51931
+ for (const pairParticipantIds of participantIdPairs) {
51932
+ const { participant: existingPairParticipant } = getPairedParticipant({
51933
+ tournamentParticipants: participants,
51934
+ participantIds: pairParticipantIds
51935
+ });
51936
+ if (!existingPairParticipant) {
51937
+ const newPairParticipant = {
51938
+ individualParticipantIds: pairParticipantIds,
51939
+ participantRole: COMPETITOR,
51940
+ participantType: PAIR
51941
+ };
51942
+ participantsToAdd.push(newPairParticipant);
51943
+ }
51944
+ }
51945
+ if (attach) {
51946
+ while (participantsToAdd.length) {
51947
+ addParticipant$1({
51948
+ participant: participantsToAdd.pop(),
51949
+ tournamentRecord
51950
+ });
51951
+ }
51952
+ const extension = { name: LINEUPS, value: lineUps };
51953
+ addExtension$1({ element: drawDefinition, extension });
51954
+ }
51955
+ return { ...SUCCESS, lineUps, participantsToAdd };
51956
+ }
51957
+
51958
+ function generateOutcomeFromScoreString(params) {
51959
+ const { matchUpFormat, matchUpStatus, winningSide, scoreString } = params;
51960
+ if (!scoreString)
51961
+ return {
51962
+ outcome: {
51963
+ ...toBePlayed,
51964
+ winningSide,
51965
+ matchUpStatus
51966
+ }
51967
+ };
51968
+ if (winningSide && ![1, 2, void 0].includes(winningSide))
51969
+ return { error: INVALID_VALUES, winningSide };
51970
+ const neutralParsedSets = scoreString && parseScoreString({ scoreString });
51971
+ const score = {};
51972
+ const winningScoreString = generateScoreString({
51973
+ sets: neutralParsedSets,
51974
+ matchUpFormat
51975
+ });
51976
+ const losingScoreString = generateScoreString({
51977
+ sets: neutralParsedSets,
51978
+ reversed: true,
51979
+ matchUpFormat
51980
+ });
51981
+ if (winningSide === 2) {
51982
+ score.scoreStringSide1 = losingScoreString;
51983
+ score.scoreStringSide2 = winningScoreString;
51984
+ } else {
51985
+ score.scoreStringSide1 = winningScoreString;
51986
+ score.scoreStringSide2 = losingScoreString;
51987
+ }
51988
+ score.sets = parseScoreString({ scoreString: score.scoreStringSide1 });
51989
+ return definedAttributes({
51990
+ outcome: {
51991
+ matchUpStatus,
51992
+ winningSide,
51993
+ score
51994
+ }
51995
+ });
51996
+ }
51997
+
51998
+ const defaultStatusProfile = {
51999
+ [WALKOVER$2]: 2,
52000
+ [DOUBLE_WALKOVER]: 1,
52001
+ [DOUBLE_DEFAULT]: 1,
52002
+ [RETIRED$1]: 1,
52003
+ [DEFAULTED]: 4
52004
+ };
52005
+ function generateOutcome(params) {
52006
+ let { defaultWithScorePercent = 2, winningSide } = params;
52007
+ const {
52008
+ matchUpStatusProfile = defaultStatusProfile,
52009
+ // { matchUpStatusProfile: {} } will always return only { matchUpStatus: COMPLETED }
52010
+ matchUpFormat = FORMAT_STANDARD,
52011
+ pointsPerMinute = 1,
52012
+ sideWeight = 4
52013
+ } = params;
52014
+ if (!isValid(matchUpFormat))
52015
+ return { error: INVALID_MATCHUP_FORMAT };
52016
+ if (typeof matchUpStatusProfile !== "object")
52017
+ return { error: INVALID_VALUES };
52018
+ if (defaultWithScorePercent > 100)
52019
+ defaultWithScorePercent = 100;
52020
+ if (isNaN(defaultWithScorePercent) || isNaN(pointsPerMinute) || isNaN(sideWeight))
52021
+ return { error: INVALID_VALUES };
52022
+ const matchUpStatuses = Object.keys(matchUpStatusProfile).filter(
52023
+ (matchUpStatus2) => Object.keys(matchUpStatusConstants).includes(matchUpStatus2) && matchUpStatus2 !== COMPLETED$1
52024
+ );
52025
+ const matchUpStatusTotals = Object.keys(matchUpStatuses).reduce(
52026
+ (total, key) => total + matchUpStatusProfile[key],
52027
+ 0
52028
+ );
52029
+ if (matchUpStatusTotals > 100)
52030
+ return { error: INVALID_VALUES, matchUpStatusProfile };
52031
+ const matchUpStatusMap = matchUpStatuses.reduce(
52032
+ (statusMap, matchUpStatus2) => {
52033
+ statusMap.pointer = statusMap.pointer + matchUpStatusProfile[matchUpStatus2];
52034
+ statusMap.valueMap.push([statusMap.pointer, matchUpStatus2]);
52035
+ return statusMap;
52036
+ },
52037
+ { pointer: 0, valueMap: [] }
52038
+ );
52039
+ const outcomePointer = randomInt(1, 100);
52040
+ const matchUpStatus = (matchUpStatusMap.valueMap.find(
52041
+ (item) => outcomePointer <= item[0]
52042
+ ) || [100, COMPLETED$1])[1];
52043
+ const noScore = { sets: [], scoreStringSide1: "", side2ScoreString: "" };
52044
+ if ([WALKOVER$2, DEFAULTED].includes(matchUpStatus)) {
52045
+ winningSide = winningSide || randomInt(1, 2);
52046
+ const outcome2 = {
52047
+ score: noScore,
52048
+ winningSide,
52049
+ matchUpStatus
52050
+ };
52051
+ const scoreDefaulted = matchUpStatus === DEFAULTED && randomInt(1, 100) > 100 - defaultWithScorePercent;
52052
+ if (!scoreDefaulted)
52053
+ return { outcome: outcome2 };
52054
+ } else if ([DOUBLE_WALKOVER, DOUBLE_DEFAULT].includes(matchUpStatus)) {
52055
+ return { outcome: { score: noScore, matchUpStatus } };
52056
+ }
52057
+ const parsedFormat = parse(matchUpFormat);
52058
+ const { bestOf, setFormat, finalSetFormat } = parsedFormat || {};
52059
+ const sets = [];
52060
+ const weightedSide = randomInt(0, 1);
52061
+ const weightedRange = winningSide ? [winningSide - 1] : [
52062
+ ...generateRange(0, sideWeight).map(() => weightedSide),
52063
+ 1 - weightedSide
52064
+ ];
52065
+ const incompleteSet = [RETIRED$1, DEFAULTED, INCOMPLETE, SUSPENDED].includes(
52066
+ matchUpStatus
52067
+ );
52068
+ const incompleteAt = incompleteSet && (randomPop(generateRange(1, bestOf)) || 1);
52069
+ let weightedWinningSide;
52070
+ for (const setNumber of generateRange(1, (bestOf || 0) + 1)) {
52071
+ const isFinalSet = setNumber === bestOf;
52072
+ const { set, incomplete, winningSideNumber } = generateSet({
52073
+ incomplete: incompleteAt === setNumber,
52074
+ matchUpStatus,
52075
+ pointsPerMinute,
52076
+ setFormat: isFinalSet && finalSetFormat || setFormat,
52077
+ setNumber,
52078
+ weightedRange
52079
+ });
52080
+ sets.push(set);
52081
+ if (incomplete) {
52082
+ weightedWinningSide = winningSideNumber;
52083
+ break;
52084
+ }
52085
+ const analysis2 = analyzeMatchUp({
52086
+ matchUp: { score: { sets }, matchUpFormat }
52087
+ });
52088
+ if (analysis2.calculatedWinningSide)
52089
+ break;
52090
+ }
52091
+ const analysis = analyzeMatchUp({
52092
+ matchUp: { score: { sets }, matchUpFormat }
52093
+ });
52094
+ const matchUpWinningSide = weightedWinningSide ? winningSide || weightedWinningSide : analysis.calculatedWinningSide;
52095
+ const { score } = matchUpScore({
52096
+ score: { sets },
52097
+ winningSide: matchUpWinningSide,
52098
+ matchUpStatus
52099
+ });
52100
+ const outcome = {
52101
+ score,
52102
+ winningSide: matchUpWinningSide,
52103
+ matchUpStatus
52104
+ };
52105
+ return { outcome };
52106
+ }
52107
+ function generateSet({
52108
+ weightedRange = [0, 1],
52109
+ pointsPerMinute,
52110
+ matchUpStatus,
52111
+ incomplete,
52112
+ setFormat,
52113
+ setNumber
52114
+ }) {
52115
+ const set = { setNumber };
52116
+ const { setTo, tiebreakFormat, tiebreakAt, tiebreakSet, timed, minutes } = setFormat;
52117
+ const weightIndex = randomInt(0, weightedRange.length - 1);
52118
+ const reverseScores = weightedRange[weightIndex];
52119
+ let winningSideNumber;
52120
+ if (timed) {
52121
+ const calcPoints = minutes * pointsPerMinute;
52122
+ const pointsVariation = Math.round(calcPoints * 0.2);
52123
+ const totalPoints = calcPoints + randomPop([1, -1]) * pointsVariation;
52124
+ const sidePoints = weightedRandom(totalPoints, 2);
52125
+ const scores = [sidePoints, totalPoints - sidePoints];
52126
+ if (reverseScores)
52127
+ scores.reverse();
52128
+ winningSideNumber = weightedRange[weightIndex] + 1;
52129
+ let highSide = scores[0] > scores[1] && 1 || scores[1] > scores[0] && 2 || 0;
52130
+ if (incomplete) {
52131
+ const [side1Score2, side2Score2] = scores;
52132
+ Object.assign(set, { side1Score: side1Score2, side2Score: side2Score2 });
52133
+ if (completedMatchUpStatuses.includes(matchUpStatus)) {
52134
+ return { set, incomplete, winningSideNumber };
52135
+ }
52136
+ return { set, incomplete };
52137
+ }
52138
+ if (!highSide)
52139
+ scores[randomInt(0, 1)] += 1;
52140
+ highSide = scores[0] > scores[1] ? 1 : 2;
52141
+ if (highSide !== winningSideNumber)
52142
+ scores.reverse();
52143
+ const [side1Score, side2Score] = scores;
52144
+ Object.assign(set, {
52145
+ side1Score,
52146
+ side2Score,
52147
+ winningSide: winningSideNumber
52148
+ });
52149
+ return { set };
52150
+ } else if (incomplete) {
52151
+ set.side1Score = randomInt(0, tiebreakAt);
52152
+ set.side2Score = randomInt(0, tiebreakAt);
52153
+ if (completedMatchUpStatuses.includes(matchUpStatus)) {
52154
+ winningSideNumber = weightedRange[weightIndex] + 1;
52155
+ }
52156
+ return { set, incomplete, winningSideNumber };
52157
+ } else {
52158
+ const range = generateRange(1, setTo + 1).map((value) => generateRange(0, setTo + 2 - value).map(() => value)).flat();
52159
+ const lowValue = range[randomInt(0, range.length - 1)];
52160
+ const scores = setTo && getSetComplement({
52161
+ isSide1: true,
52162
+ tiebreakAt,
52163
+ lowValue,
52164
+ setTo
52165
+ });
52166
+ const isTiebreakSet = !scores;
52167
+ const specifiedWinningSide = weightedRange.length === 1 && weightedRange[weightIndex] + 1;
52168
+ if (!isTiebreakSet) {
52169
+ if (specifiedWinningSide) {
52170
+ const highSide = scores[0] > scores[1] ? 1 : 2;
52171
+ if (highSide !== specifiedWinningSide)
52172
+ scores.reverse();
52173
+ } else if (reverseScores) {
52174
+ scores.reverse();
52175
+ }
52176
+ const [side1Score, side2Score] = scores;
52177
+ Object.assign(set, { side1Score, side2Score });
52178
+ }
52179
+ const setAnalysis = analyzeSet({
52180
+ matchUpScoringFormat: { setFormat },
52181
+ setObject: set
52182
+ });
52183
+ let tiebreakWinningSide;
52184
+ if (setAnalysis.hasTiebreakCondition || isTiebreakSet) {
52185
+ const { NoAD: tiebreakNoAd, tiebreakTo } = tiebreakFormat || tiebreakSet || {};
52186
+ const range2 = generateRange(1, tiebreakTo + 1).map(
52187
+ (value) => generateRange(0, tiebreakTo + 2 - value).map(() => value)
52188
+ ).flat();
52189
+ const lowValue2 = range2[randomInt(0, range2.length - 1)];
52190
+ const scores2 = getTiebreakComplement({
52191
+ isSide1: true,
52192
+ tiebreakNoAd,
52193
+ tiebreakTo,
52194
+ lowValue: lowValue2
52195
+ });
52196
+ if (scores2) {
52197
+ if (isTiebreakSet) {
52198
+ const highSide = scores2[0] > scores2[1] ? 1 : 2;
52199
+ if (specifiedWinningSide) {
52200
+ if (highSide !== specifiedWinningSide)
52201
+ scores2.reverse();
52202
+ } else if (reverseScores) {
52203
+ scores2.reverse();
52204
+ }
52205
+ [set.side1TiebreakScore, set.side2TiebreakScore] = scores2;
52206
+ tiebreakWinningSide = scores2[0] > scores2[1] && 1 || scores2[1] > scores2[0] && 2 || void 0;
52207
+ } else if (setAnalysis.leadingSide === 2) {
52208
+ [set.side1TiebreakScore, set.side2TiebreakScore] = scores2;
52209
+ } else {
52210
+ [set.side2TiebreakScore, set.side1TiebreakScore] = scores2;
52211
+ }
52212
+ }
52213
+ }
52214
+ set.winningSide = setAnalysis.winningSide || setAnalysis.leadingSide || specifiedWinningSide || tiebreakWinningSide;
52215
+ }
52216
+ return { set };
52217
+ }
52218
+
52219
+ function completeDrawMatchUps(params) {
52220
+ const {
52221
+ matchUpStatusProfile,
52222
+ // { matchUpStatusProfile: {} } will always return only { matchUpStatus: COMPLETED }
52223
+ completeAllMatchUps,
52224
+ // qualifyingProfiles, // CONSIDER: allowing completionGoal per structureProfile
52225
+ randomWinningSide,
52226
+ tournamentRecord,
52227
+ completionGoal,
52228
+ drawDefinition,
52229
+ event
52230
+ } = params;
52231
+ if (!drawDefinition)
52232
+ return { error: MISSING_DRAW_DEFINITION };
52233
+ const matchUpFormat = params.matchUpFormat || drawDefinition.matchUpFormat || event?.matchUpFormat;
52234
+ const sortedStructures = drawDefinition.structures.slice().sort(structureSort);
52235
+ let completedCount = 0;
52236
+ const { matchUps: firstRoundDualMatchUps, matchUpsMap } = getAllDrawMatchUps({
52237
+ contextFilters: {
52238
+ stages: [MAIN, QUALIFYING]
52239
+ },
52240
+ matchUpFilters: {
52241
+ matchUpTypes: [TEAM$2],
52242
+ roundNumbers: [1]
52243
+ },
52244
+ inContext: true,
52245
+ drawDefinition
52246
+ });
52247
+ if (firstRoundDualMatchUps?.length) {
52248
+ const categoryName = event?.category?.ageCategoryCode || event?.category?.categoryName;
52249
+ if (categoryName) {
52250
+ const scaleAccessor = {
52251
+ scaleName: categoryName,
52252
+ sortOrder: ASCENDING,
52253
+ scaleType: RANKING$1
52254
+ };
52255
+ generateLineUps({
52256
+ singlesOnly: true,
52257
+ tournamentRecord,
52258
+ drawDefinition,
52259
+ scaleAccessor,
52260
+ attach: true,
52261
+ event
52262
+ });
52263
+ } else {
52264
+ const structureId = firstRoundDualMatchUps[0]?.structureId;
52265
+ const { positionAssignments } = getPositionAssignments$1({
52266
+ drawDefinition,
52267
+ structureId
52268
+ });
52269
+ if (positionAssignments?.length) {
52270
+ const { tournamentParticipants: teamParticipants } = getTournamentParticipants({
52271
+ participantFilters: { participantTypes: [TEAM$2] },
52272
+ tournamentRecord
52273
+ });
52274
+ const assignParticipants = (dualMatchUp) => {
52275
+ const singlesMatchUps = dualMatchUp.tieMatchUps.filter(
52276
+ ({ matchUpType }) => matchUpType === SINGLES$1
52277
+ );
52278
+ const doublesMatchUps = dualMatchUp.tieMatchUps.filter(
52279
+ ({ matchUpType }) => matchUpType === DOUBLES$1
52280
+ );
52281
+ singlesMatchUps.forEach((singlesMatchUp, i) => {
52282
+ const tieMatchUpId = singlesMatchUp.matchUpId;
52283
+ singlesMatchUp.sides.forEach((side) => {
52284
+ const { drawPosition } = side;
52285
+ const teamParticipant = teamParticipants?.find(
52286
+ (teamParticipant2) => {
52287
+ const { participantId } = teamParticipant2;
52288
+ const assignment = positionAssignments.find(
52289
+ (assignment2) => assignment2.participantId === participantId
52290
+ );
52291
+ return assignment?.drawPosition === drawPosition;
52292
+ }
52293
+ );
52294
+ if (teamParticipant) {
52295
+ const individualParticipantId = teamParticipant.individualParticipantIds[i];
52296
+ assignTieMatchUpParticipantId({
52297
+ teamParticipantId: teamParticipant.participantId,
52298
+ participantId: individualParticipantId,
52299
+ tournamentRecord,
52300
+ drawDefinition,
52301
+ tieMatchUpId,
52302
+ event
52303
+ });
52304
+ }
52305
+ });
52306
+ });
52307
+ doublesMatchUps.forEach((doublesMatchUp, i) => {
52308
+ const tieMatchUpId = doublesMatchUp.matchUpId;
52309
+ doublesMatchUp.sides.forEach((side) => {
52310
+ const { drawPosition } = side;
52311
+ const teamParticipant = teamParticipants?.find(
52312
+ (teamParticipant2) => {
52313
+ const { participantId } = teamParticipant2;
52314
+ const assignment = positionAssignments.find(
52315
+ (assignment2) => assignment2.participantId === participantId
52316
+ );
52317
+ return assignment?.drawPosition === drawPosition;
52318
+ }
52319
+ );
52320
+ if (teamParticipant) {
52321
+ const individualParticipantIds = teamParticipant.individualParticipantIds.slice(
52322
+ i * 2,
52323
+ i * 2 + 2
52324
+ );
52325
+ individualParticipantIds.forEach((individualParticipantId) => {
52326
+ assignTieMatchUpParticipantId({
52327
+ teamParticipantId: teamParticipant.participantId,
52328
+ participantId: individualParticipantId,
52329
+ tournamentRecord,
52330
+ drawDefinition,
52331
+ tieMatchUpId,
52332
+ event
52333
+ });
52334
+ });
52335
+ }
52336
+ });
52337
+ });
52338
+ };
52339
+ firstRoundDualMatchUps.forEach(assignParticipants);
52340
+ }
52341
+ }
52342
+ }
52343
+ const scoreString = typeof completeAllMatchUps === "string" && completeAllMatchUps;
52344
+ const matchUpStatus = scoreString && COMPLETED$1;
52345
+ for (const structure of sortedStructures) {
52346
+ if (completedCount >= completionGoal)
52347
+ break;
52348
+ const { matchUps } = getAllStructureMatchUps({
52349
+ matchUpFilters: { matchUpTypes: [DOUBLES$1, SINGLES$1] },
52350
+ afterRecoveryTimes: false,
52351
+ tournamentRecord,
52352
+ inContext: true,
52353
+ drawDefinition,
52354
+ matchUpsMap,
52355
+ structure,
52356
+ event
52357
+ });
52358
+ const sortedMatchUpIds = matchUps.filter(({ winningSide }) => !winningSide).sort(matchUpSort).map(getMatchUpId);
52359
+ for (const matchUpId of sortedMatchUpIds) {
52360
+ if (!isNaN(completionGoal) && completedCount >= completionGoal)
52361
+ break;
52362
+ const { matchUps: matchUps2 } = getAllStructureMatchUps({
52363
+ matchUpFilters: { matchUpTypes: [DOUBLES$1, SINGLES$1] },
52364
+ afterRecoveryTimes: false,
52365
+ tournamentRecord,
52366
+ inContext: true,
52367
+ drawDefinition,
52368
+ matchUpsMap,
52369
+ structure,
52370
+ event
52371
+ });
52372
+ const targetMatchUp = matchUps2.find(
52373
+ (matchUp) => matchUp.matchUpId === matchUpId
52374
+ );
52375
+ const isDoubleExit = [DOUBLE_WALKOVER, DOUBLE_DEFAULT].includes(
52376
+ targetMatchUp.matchUpStatus
52377
+ );
52378
+ if (targetMatchUp?.readyToScore && !isDoubleExit) {
52379
+ const result = smartComplete({
52380
+ winningSide: !randomWinningSide && 1,
52381
+ matchUpStatusProfile,
52382
+ tournamentRecord,
52383
+ drawDefinition,
52384
+ targetMatchUp,
52385
+ matchUpFormat,
52386
+ matchUpStatus,
52387
+ scoreString,
52388
+ event
52389
+ });
52390
+ if (result?.error)
52391
+ return result;
52392
+ completedCount += 1;
52393
+ }
52394
+ }
52395
+ }
52396
+ return { ...SUCCESS, completedCount };
52397
+ }
52398
+ function completeDrawMatchUp(params) {
52399
+ const {
52400
+ matchUpStatusCodes,
52401
+ policyDefinitions,
52402
+ tournamentRecord,
52403
+ drawDefinition,
52404
+ targetMatchUp,
52405
+ matchUpStatus,
52406
+ matchUpFormat,
52407
+ scoreString,
52408
+ winningSide,
52409
+ event
52410
+ } = params;
52411
+ if (!targetMatchUp || targetMatchUp.matchUpStatus === BYE) {
52412
+ return;
52413
+ }
52414
+ const { matchUpId } = targetMatchUp || {};
52415
+ const { outcome } = generateOutcomeFromScoreString({
52416
+ matchUpFormat,
52417
+ matchUpStatus,
52418
+ scoreString,
52419
+ winningSide
52420
+ });
52421
+ if (matchUpStatusCodes)
52422
+ outcome.matchUpStatusCodes = matchUpStatusCodes;
52423
+ return setMatchUpStatus$1({
52424
+ tournamentRecord,
52425
+ policyDefinitions,
52426
+ drawDefinition,
52427
+ matchUpFormat,
52428
+ matchUpId,
52429
+ outcome,
52430
+ event
52431
+ });
52432
+ }
52433
+ function smartComplete(params) {
52434
+ const {
52435
+ matchUpStatusProfile = {},
52436
+ tournamentRecord,
52437
+ policyDefinitions,
52438
+ drawDefinition,
52439
+ matchUpStatus,
52440
+ matchUpFormat,
52441
+ targetMatchUp,
52442
+ scoreString,
52443
+ winningSide,
52444
+ event
52445
+ } = params;
52446
+ if (scoreString || matchUpStatus)
52447
+ return completeDrawMatchUp(params);
52448
+ const { matchUpId } = targetMatchUp || {};
52449
+ const { outcome } = generateOutcome({
52450
+ matchUpStatusProfile,
52451
+ matchUpFormat,
52452
+ winningSide
52453
+ });
52454
+ return setMatchUpStatus$1({
52455
+ policyDefinitions,
52456
+ tournamentRecord,
52457
+ drawDefinition,
52458
+ matchUpFormat,
52459
+ matchUpId,
52460
+ outcome,
52461
+ event
52462
+ });
52463
+ }
52464
+
52465
+ function convertPointEight({ tournament }) {
52466
+ if (!tournament)
52467
+ return { error: MISSING_TOURNAMENT_RECORD };
52468
+ const {
52469
+ providerTournamentID: tournamentId,
52470
+ hostCountryCode,
52471
+ tournamentLevel,
52472
+ totalPrizeMoney,
52473
+ tournamentName,
52474
+ extensions,
52475
+ startDate,
52476
+ endDate
52477
+ } = tournament;
52478
+ const tournamentRecord = newTournamentRecord({
52479
+ hostCountryCode,
52480
+ tournamentLevel,
52481
+ totalPrizeMoney,
52482
+ tournamentName,
52483
+ tournamentId,
52484
+ extensions,
52485
+ startDate,
52486
+ endDate
52487
+ });
52488
+ tournamentRecord.events = [];
52489
+ for (const legacyEvent of tournament.events || []) {
52490
+ const {
52491
+ extensions: extensions2,
52492
+ ageCategory,
52493
+ discipline,
52494
+ eventType,
52495
+ eventId,
52496
+ gender,
52497
+ stages
52498
+ } = legacyEvent;
52499
+ const event = {
52500
+ drawDefinitions: deriveDraws(stages),
52501
+ category: { ageCategory },
52502
+ gender: ["M", MALE].includes(gender) && MALE || ["F", FEMALE].includes(gender) && FEMALE || void 0,
52503
+ eventType: ["D", DOUBLES].includes(eventType) && DOUBLES || ["T", TEAM$1].includes(eventType) ? TEAM$1 : SINGLES,
52504
+ extensions: extensions2,
52505
+ discipline,
52506
+ eventId
52507
+ };
52508
+ tournamentRecord.events.push(event);
52509
+ }
52510
+ return { ...SUCCESS, tournamentRecord };
52511
+ }
52512
+ function deriveDraws(stages) {
52513
+ const drawDefinitions = [];
52514
+ for (const legacyStage of stages || []) {
52515
+ const { stageType } = legacyStage;
52516
+ const stage = ["M", MAIN].includes(stageType) && MAIN || ["Q", QUALIFYING].includes(stageType) && QUALIFYING || ["C", CONSOLATION].includes(stageType) && CONSOLATION || ["P", PLAY_OFF].includes(stageType) && PLAY_OFF || void 0;
52517
+ for (const draw of legacyStage.draws || []) {
52518
+ const { drawId, drawSize, matchUps } = draw;
52519
+ const drawDefinition = { stage, drawId, drawSize };
52520
+ drawDefinitions.push(drawDefinition);
52521
+ console.log(
52522
+ matchUps.map(({ roundNumber, roundPosition }) => ({
52523
+ roundNumber,
52524
+ roundPosition
52525
+ })),
52526
+ { draw, drawDefinition }
52527
+ );
52528
+ }
52529
+ }
52530
+ return drawDefinitions;
52531
+ }
52532
+
52533
+ const ABANDONED = "ABANDONED";
52534
+ const ACTIVE = "ACTIVE";
52535
+ const CANCELLED = "CANCELLED";
52536
+ const COMPLETED = "COMPLETED";
52537
+ const IN_PROGRESS = "IN_PROGRESS";
52538
+ const tournamentConstants = {
52539
+ ABANDONED,
52540
+ ACTIVE,
52541
+ CANCELLED,
52542
+ COMPLETED,
52543
+ IN_PROGRESS
52544
+ };
52545
+
52546
+ function setTournamentStatus({ tournamentRecord, status }) {
52547
+ if (!tournamentRecord)
52548
+ return { error: MISSING_TOURNAMENT_RECORD };
52549
+ if (status && !Object.keys(tournamentConstants).includes(status))
52550
+ return { error: INVALID_VALUES, info: "Unknown status" };
52551
+ tournamentRecord.tournamentStatus = status;
52552
+ return { ...SUCCESS };
52553
+ }
52554
+
52555
+ function analyzeDraws({ tournamentRecord }) {
52556
+ if (!tournamentRecord)
52557
+ return { error: MISSING_TOURNAMENT_RECORD };
52558
+ const drawsAnalysis = {
52559
+ positionsNoOutcomes: [],
52560
+ // all positions assigned and no outcomes
52561
+ canBePruned: [],
52562
+ // partially assigned positions with outcomes => drawSizes can be reduced
52563
+ matchPlay: [],
52564
+ // only first round has active matchUps; some unassigned positions
52565
+ inactive: [],
52566
+ drawAnalysis: {}
52567
+ };
52568
+ const eventsMap = {};
52569
+ const eventDraws = tournamentRecord.events?.map((event) => {
52570
+ const eventId = event.eventId;
52571
+ eventsMap[eventId] = event;
52572
+ return (event?.drawDefinitions || []).map((drawDefinition) => ({
52573
+ drawDefinition,
52574
+ eventId
52575
+ }));
52576
+ }).flat().filter(Boolean);
52577
+ eventDraws.forEach(({ drawDefinition, eventId }) => {
52578
+ let positionsAssignedCount = 0;
52579
+ let matchUpsWithWinningSideCount = 0;
52580
+ let matchUpsNoOutcomeCount = 0;
52581
+ const { allStructuresLinked } = getStructureGroups({ drawDefinition });
52582
+ const event = eventsMap[eventId];
52583
+ const structures = drawDefinition?.structures || [];
52584
+ const structuresData = structures.map((structure) => {
52585
+ const { stage, stageSequence, structureId } = structure;
52586
+ const orderNumber = stageOrder$1[stage];
52587
+ const { inContextStructureMatchUps } = getStructureDrawPositionProfiles({
52588
+ drawDefinition,
52589
+ structure,
52590
+ event
52591
+ });
52592
+ const matchUpsWithWinningSide = inContextStructureMatchUps?.filter(
52593
+ ({ winningSide }) => winningSide
52594
+ );
52595
+ const winningSideCount = matchUpsWithWinningSide.filter(Boolean).length || 0;
52596
+ matchUpsWithWinningSideCount += winningSideCount;
52597
+ matchUpsNoOutcomeCount += inContextStructureMatchUps.length - matchUpsWithWinningSideCount;
52598
+ const maxWinningSideFirstRoundPosition = Math.max(
52599
+ matchUpsWithWinningSide.filter(({ roundNumber }) => roundNumber === 1).map(({ roundPosition }) => roundPosition)
52600
+ );
52601
+ const { positionAssignments } = getPositionAssignments$1({ structure });
52602
+ const positionsAssigned = positionAssignments?.filter(
52603
+ ({ participantId }) => participantId
52604
+ );
52605
+ positionsAssignedCount += positionsAssigned?.length || 0;
52606
+ const unassignedPositionsCount = (positionAssignments?.length || 0) - (positionsAssigned?.length || 0);
52607
+ const { roundMatchUps, roundProfile, roundNumbers, maxMatchUpsCount } = getRoundMatchUps$1({ matchUps: inContextStructureMatchUps });
52608
+ const activeRounds = roundProfile && Object.keys(roundProfile).filter((roundNumber) => !roundProfile[roundNumber].inactiveRound).map((roundNumber) => parseInt(roundNumber));
52609
+ const inactiveRounds = roundProfile && Object.keys(roundProfile).filter((roundNumber) => roundProfile[roundNumber].inactiveRound).map((roundNumber) => parseInt(roundNumber));
52610
+ const inactiveStructure = roundProfile && Object.values(roundProfile).every((profile) => profile.inactiveRound);
52611
+ return {
52612
+ positionsAssignedCount: positionsAssigned?.length || 0,
52613
+ maxWinningSideFirstRoundPosition,
52614
+ unassignedPositionsCount,
52615
+ inactiveStructure,
52616
+ maxMatchUpsCount,
52617
+ inactiveRounds,
52618
+ roundMatchUps,
52619
+ activeRounds,
52620
+ roundNumbers,
52621
+ roundProfile,
52622
+ structureId,
52623
+ stageSequence,
52624
+ orderNumber,
52625
+ stage
52626
+ };
52627
+ });
52628
+ const mainStructure = structuresData.find(
52629
+ (data) => data.orderNumber === 2 && data.stageSequence === 1
52630
+ );
52631
+ const activeStructuresCount = structuresData.filter(
52632
+ ({ inactiveStructure }) => !inactiveStructure
52633
+ ).length;
52634
+ const { links } = getStructureLinks({
52635
+ drawDefinition,
52636
+ structureId: mainStructure.structureId
52637
+ });
52638
+ const isMatchPlay = ensureInt(mainStructure.activeRounds[0]) === 1 && mainStructure.activeRounds.length === 1 && activeStructuresCount === 1;
52639
+ const inactiveDraw = structuresData?.every(
52640
+ ({ inactiveStructure }) => inactiveStructure
52641
+ );
52642
+ const canBePruned = !links.length && mainStructure.activeRounds.length && (mainStructure.roundProfile[1].inactiveCount || mainStructure.inactiveRounds.length);
52643
+ const drawId = drawDefinition.drawId;
52644
+ if (positionsAssignedCount && !matchUpsWithWinningSideCount)
52645
+ drawsAnalysis.positionsNoOutcomes.push(drawId);
52646
+ if (inactiveDraw)
52647
+ drawsAnalysis.inactive.push(drawId);
52648
+ if (isMatchPlay)
52649
+ drawsAnalysis.matchPlay.push(drawId);
52650
+ if (canBePruned)
52651
+ drawsAnalysis.canBePruned.push(drawId);
52652
+ const drawAnalysis = {
52653
+ matchUpsWithWinningSideCount,
52654
+ matchUpsNoOutcomeCount,
52655
+ positionsAssignedCount,
52656
+ allStructuresLinked,
52657
+ structuresData,
52658
+ inactiveDraw,
52659
+ isMatchPlay,
52660
+ drawId
52661
+ };
52662
+ drawsAnalysis.drawAnalysis[drawId] = drawAnalysis;
52663
+ });
52664
+ return { ...SUCCESS, drawsAnalysis };
52665
+ }
52666
+
52667
+ function checkIsDual(tournamentRecord) {
52668
+ const teamParticipants = tournamentRecord.participants?.filter(
52669
+ ({ participantType }) => participantType === TEAM
52670
+ );
52671
+ const twoTeams = teamParticipants?.length === 2;
52672
+ const event = tournamentRecord.events?.length === 1 && tournamentRecord.events[0];
52673
+ const drawDefinition = event?.drawDefinitions?.length === 1 && event.drawDefinitions[0];
52674
+ const structure = drawDefinition?.structures?.length === 1 && drawDefinition.structures[0];
52675
+ const twoDrawPositions = structure?.positionAssignments?.length === 2;
52676
+ return !!(event.tieFormat && twoTeams && twoDrawPositions);
52677
+ }
52678
+
52679
+ function analyzeTournament({ tournamentRecord }) {
52680
+ if (!tournamentRecord)
52681
+ return { error: MISSING_TOURNAMENT_RECORD };
52682
+ const { drawsAnalysis } = analyzeDraws({ tournamentRecord });
52683
+ const analysis = {
52684
+ isDual: checkIsDual(tournamentRecord),
52685
+ drawsAnalysis
52686
+ };
52687
+ return { ...SUCCESS, analysis };
52688
+ }
52689
+
52690
+ function setTournamentName({
52691
+ tournamentRecord,
52692
+ promotionalName,
52693
+ tournamentName,
52694
+ formalName
52695
+ }) {
52696
+ if (!tournamentRecord)
52697
+ return { error: MISSING_TOURNAMENT_RECORD };
52698
+ if (tournamentName)
52699
+ tournamentRecord.tournamentName = tournamentName;
52700
+ if (promotionalName)
52701
+ tournamentRecord.promotionalName = promotionalName;
52702
+ if (formalName)
52703
+ tournamentRecord.formalName = formalName;
52704
+ if (tournamentRecord.promotionalName === tournamentRecord.tournamentName) {
52705
+ delete tournamentRecord.promotionalName;
52706
+ }
52707
+ if (tournamentRecord.formalName === tournamentRecord.tournamentName) {
52708
+ delete tournamentRecord.formalName;
52709
+ }
52710
+ return { ...SUCCESS };
52711
+ }
52712
+ function setTournamentNotes({ tournamentRecord, notes }) {
52713
+ if (!tournamentRecord)
52714
+ return { error: MISSING_TOURNAMENT_RECORD };
52715
+ return addNotes({ element: tournamentRecord, notes });
52716
+ }
52717
+ function setTournamentCategories({ tournamentRecord, categories }) {
52718
+ if (!tournamentRecord)
52719
+ return { error: MISSING_TOURNAMENT_RECORD };
52720
+ categories = (categories || []).filter((category) => {
52721
+ return category.categoryName && category.type;
52722
+ });
52723
+ tournamentRecord.tournamentCategories = categories;
52724
+ return { ...SUCCESS };
52725
+ }
52726
+
52727
+ function updateCourtAvailability({ tournamentRecord }) {
52728
+ if (!tournamentRecord)
52729
+ return { error: MISSING_TOURNAMENT_RECORD };
52730
+ const { startDate, endDate } = tournamentRecord;
52731
+ const tournamentDates = dateRange(startDate, endDate);
52732
+ const courts = [];
52733
+ for (const venue of tournamentRecord.venues || []) {
52734
+ if (venue?.courts?.length)
52735
+ courts.push(...venue.courts);
52736
+ }
52737
+ for (const court of courts) {
52738
+ const { startTime, endTime } = (court.dateAvailability || []).reduce(
52739
+ (extents, availability) => {
52740
+ const startMinutes = timeStringMinutes(extents.startTime);
52741
+ const endMinutes = timeStringMinutes(extents.endTime);
52742
+ if (availability.startTime && timeStringMinutes(availability.startTime) < startMinutes)
52743
+ extents.startTime = availability.startTime;
52744
+ if (availability.endTime && timeStringMinutes(availability.endTime) > endMinutes)
52745
+ extents.endTime = availability.endTime;
52746
+ return extents;
52747
+ },
52748
+ { startTime: "08:00", endTime: "18:00" }
52749
+ );
52750
+ const updatedDateAvailability = tournamentDates.map((date) => {
52751
+ const existing = court.dateAvailability?.find(
52752
+ (availability) => availability.date === date
52753
+ );
52754
+ return existing || { date, startTime, endTime };
52755
+ });
52756
+ court.dateAvailability = updatedDateAvailability;
52757
+ }
52758
+ return { ...SUCCESS };
52759
+ }
52760
+
52761
+ function setTournamentDates({
52762
+ tournamentRecord,
52763
+ startDate,
52764
+ endDate
52765
+ }) {
52766
+ if (!tournamentRecord)
52767
+ return { error: MISSING_TOURNAMENT_RECORD };
52768
+ if (startDate && !dateValidation.test(startDate) || endDate && !dateValidation.test(endDate))
52769
+ return { error: INVALID_DATE };
52770
+ if (!startDate && !endDate)
52771
+ return { error: MISSING_DATE };
52772
+ if (endDate && startDate && new Date(endDate) < new Date(startDate))
52773
+ return { error: INVALID_VALUES };
52774
+ let checkScheduling;
52775
+ if (startDate && tournamentRecord.startDate && new Date(startDate) > new Date(tournamentRecord.startDate) || endDate && tournamentRecord.endDate && new Date(endDate) < new Date(tournamentRecord.endDate)) {
52776
+ checkScheduling = true;
52777
+ }
52778
+ if (startDate)
52779
+ tournamentRecord.startDate = startDate;
52780
+ if (endDate)
52781
+ tournamentRecord.endDate = endDate;
52782
+ if (startDate && tournamentRecord.endDate && new Date(startDate) > new Date(tournamentRecord.endDate)) {
52783
+ tournamentRecord.endDate = startDate;
52784
+ }
52785
+ if (endDate && tournamentRecord.startDate && new Date(endDate) < new Date(tournamentRecord.startDate)) {
52786
+ tournamentRecord.startDate = endDate;
52787
+ }
52788
+ const unscheduledMatchUpIds = checkScheduling && removeInvalidScheduling({ tournamentRecord })?.unscheduledMatchUpIds;
52789
+ updateCourtAvailability({ tournamentRecord });
52790
+ addNotice({
52791
+ topic: MODIFY_TOURNAMENT_DETAIL,
52792
+ payload: { startDate, endDate }
52793
+ });
52794
+ return { ...SUCCESS, unscheduledMatchUpIds };
52795
+ }
52796
+ function setTournamentStartDate({ tournamentRecord, startDate }) {
52797
+ return setTournamentDates({ tournamentRecord, startDate });
52798
+ }
52799
+ function setTournamentEndDate({ tournamentRecord, endDate }) {
52800
+ return setTournamentDates({ tournamentRecord, endDate });
52801
+ }
52802
+ function removeInvalidScheduling({ tournamentRecord }) {
52803
+ const matchUps = allTournamentMatchUps({ tournamentRecord }).matchUps ?? [];
52804
+ const startDate = tournamentRecord.startDate && new Date(tournamentRecord.startDate);
52805
+ const endDate = tournamentRecord.endDate && new Date(tournamentRecord.endDate);
52806
+ const invalidScheduledDates = [];
52807
+ const invalidSchedulingMatchUpIds = [];
52808
+ for (const matchUp of matchUps) {
52809
+ const { schedule, matchUpId } = matchUp;
52810
+ if (!schedule)
52811
+ continue;
52812
+ if (schedule.scheduledDate) {
52813
+ const scheduledDate = new Date(schedule.scheduledDate);
52814
+ if (startDate && scheduledDate < startDate || endDate && scheduledDate > endDate) {
52815
+ invalidSchedulingMatchUpIds.push(matchUpId);
52816
+ if (!invalidScheduledDates.includes(schedule.scheduledDate))
52817
+ invalidScheduledDates.push(schedule.scheduledDate);
52818
+ }
52819
+ }
52820
+ }
51641
52821
  if (invalidScheduledDates.length) {
51642
52822
  const result = clearScheduledMatchUps$1({
51643
52823
  scheduledDates: invalidScheduledDates,
@@ -51654,6 +52834,7 @@ const tournamentGovernor = {
51654
52834
  removeNotes,
51655
52835
  analyzeDraws,
51656
52836
  analyzeTournament,
52837
+ completeDrawMatchUps,
51657
52838
  getRounds,
51658
52839
  getProfileRounds,
51659
52840
  setTournamentName,
@@ -52472,161 +53653,6 @@ function removeMatchUpSideParticipant({
52472
53653
  return { ...SUCCESS };
52473
53654
  }
52474
53655
 
52475
- function validateLineUp({ lineUp, tieFormat }) {
52476
- const errors = [];
52477
- if (!Array.isArray(lineUp)) {
52478
- errors.push(mustBeAnArray("lineUp"));
52479
- return { valid: false, errors, error: INVALID_VALUES };
52480
- }
52481
- const validItems = lineUp.every((item) => {
52482
- if (typeof item !== "object") {
52483
- errors.push(`lineUp entries must be objects`);
52484
- return false;
52485
- }
52486
- const { participantId, collectionAssignments } = item;
52487
- if (!participantId) {
52488
- errors.push("Missing participantId");
52489
- return false;
52490
- }
52491
- if (typeof participantId !== "string") {
52492
- errors.push("participantIds must be strings");
52493
- return false;
52494
- }
52495
- if (!Array.isArray(collectionAssignments)) {
52496
- errors.push(mustBeAnArray("collectionAssignments"));
52497
- return false;
52498
- }
52499
- return collectionAssignments.every((collectionAssignment) => {
52500
- if (typeof collectionAssignment !== "object") {
52501
- errors.push("collectionAssignments must be objects");
52502
- return false;
52503
- }
52504
- const { collectionPosition } = collectionAssignment;
52505
- if (typeof collectionPosition !== "number") {
52506
- errors.push("collectionPosition must be a number");
52507
- return false;
52508
- }
52509
- return true;
52510
- });
52511
- });
52512
- const noDuplicates = unique(lineUp.map(getParticipantId)).length === lineUp.length;
52513
- if (!noDuplicates)
52514
- errors.push("Duplicated participantId(s)");
52515
- const valid = validItems && noDuplicates;
52516
- return { valid, errors, error: errors.length ? INVALID_VALUES : void 0 };
52517
- }
52518
-
52519
- function updateTeamLineUp({
52520
- drawDefinition,
52521
- participantId,
52522
- tieFormat,
52523
- lineUp
52524
- }) {
52525
- if (typeof drawDefinition !== "object")
52526
- return { error: MISSING_DRAW_DEFINITION };
52527
- if (typeof participantId !== "string")
52528
- return { error: MISSING_PARTICIPANT_ID };
52529
- const validation = validateLineUp({ lineUp, tieFormat });
52530
- if (!validation.valid)
52531
- return validation;
52532
- const { extension: existingExtension } = findExtension({
52533
- element: drawDefinition,
52534
- name: LINEUPS
52535
- });
52536
- const value = existingExtension?.value || {};
52537
- value[participantId] = removeLineUpSubstitutions({ lineUp });
52538
- const extension = { name: LINEUPS, value };
52539
- addExtension$1({ element: drawDefinition, extension });
52540
- addDrawNotice({ drawDefinition });
52541
- return { ...SUCCESS };
52542
- }
52543
-
52544
- function getTieMatchUpContext({
52545
- tournamentRecord,
52546
- drawDefinition,
52547
- tieMatchUpId,
52548
- event
52549
- }) {
52550
- if (!tournamentRecord)
52551
- return { error: MISSING_TOURNAMENT_RECORD };
52552
- if (!drawDefinition)
52553
- return { error: MISSING_DRAW_ID };
52554
- if (!event)
52555
- return { error: EVENT_NOT_FOUND };
52556
- const matchUpsMap = getMatchUpsMap({ drawDefinition });
52557
- const { matchUp: tieMatchUp } = findMatchUp$1({
52558
- matchUpId: tieMatchUpId,
52559
- drawDefinition,
52560
- matchUpsMap
52561
- });
52562
- if (!tieMatchUp)
52563
- return { error: MATCHUP_NOT_FOUND };
52564
- const { matchUp: inContextTieMatchUp, structure } = findMatchUp$1({
52565
- tournamentParticipants: tournamentRecord.participants,
52566
- matchUpId: tieMatchUpId,
52567
- inContext: true,
52568
- drawDefinition,
52569
- matchUpsMap,
52570
- event
52571
- });
52572
- if (!inContextTieMatchUp)
52573
- return { error: MATCHUP_NOT_FOUND };
52574
- const {
52575
- collectionPosition,
52576
- drawPositions,
52577
- collectionId,
52578
- matchUpTieId,
52579
- matchUpType
52580
- } = inContextTieMatchUp;
52581
- if (matchUpType && ![SINGLES$1, DOUBLES$1].includes(matchUpType))
52582
- return { error: INVALID_MATCHUP };
52583
- const { positionAssignments } = getPositionAssignments$1({ structure });
52584
- const relevantAssignments = positionAssignments?.filter(
52585
- (assignment) => drawPositions?.includes(assignment.drawPosition)
52586
- );
52587
- const participantIds = relevantAssignments?.map(
52588
- extractAttributes("participantId")
52589
- );
52590
- const { tournamentParticipants: teamParticipants } = getTournamentParticipants({
52591
- tournamentRecord,
52592
- participantFilters: {
52593
- participantTypes: [TEAM],
52594
- participantIds
52595
- }
52596
- });
52597
- const { matchUp: dualMatchUp } = findMatchUp$1({
52598
- matchUpId: matchUpTieId,
52599
- drawDefinition,
52600
- matchUpsMap
52601
- });
52602
- const { matchUp: inContextDualMatchUp } = findMatchUp$1({
52603
- matchUpId: matchUpTieId,
52604
- inContext: true,
52605
- drawDefinition,
52606
- matchUpsMap
52607
- });
52608
- const tieFormat = resolveTieFormat({
52609
- matchUp: dualMatchUp,
52610
- drawDefinition,
52611
- structure,
52612
- event
52613
- })?.tieFormat;
52614
- return {
52615
- inContextDualMatchUp,
52616
- inContextTieMatchUp,
52617
- relevantAssignments,
52618
- collectionPosition,
52619
- teamParticipants,
52620
- collectionId,
52621
- matchUpType,
52622
- dualMatchUp,
52623
- tieMatchUp,
52624
- tieFormat,
52625
- structure,
52626
- ...SUCCESS
52627
- };
52628
- }
52629
-
52630
53656
  function replaceTieMatchUpParticipantId(params) {
52631
53657
  const matchUpContext = getTieMatchUpContext(params);
52632
53658
  if (matchUpContext.error)
@@ -52880,338 +53906,6 @@ function replaceTieMatchUpParticipantId(params) {
52880
53906
  return { ...SUCCESS, modifiedLineUp, participantRemoved, participantAdded };
52881
53907
  }
52882
53908
 
52883
- function removeCollectionAssignments({
52884
- collectionPosition,
52885
- teamParticipantId,
52886
- dualMatchUpSide,
52887
- drawDefinition,
52888
- participantIds,
52889
- collectionId
52890
- }) {
52891
- if (!collectionId || !collectionPosition || !Array.isArray(participantIds))
52892
- return {
52893
- modifiedLineUp: dualMatchUpSide?.lineUp || [],
52894
- error: INVALID_VALUES
52895
- };
52896
- const lineUp = dualMatchUpSide?.lineUp || getTeamLineUp({
52897
- participantId: teamParticipantId,
52898
- drawDefinition
52899
- })?.lineUp;
52900
- const previousParticipantIds = [];
52901
- const assignmentsRemoved = [];
52902
- const modifiedLineUp = lineUp?.map((teamCompetitor) => {
52903
- if (!participantIds.includes(teamCompetitor.participantId)) {
52904
- return teamCompetitor;
52905
- }
52906
- const collectionAssignments = teamCompetitor.collectionAssignments?.filter((assignment) => {
52907
- const target = assignment.collectionId === collectionId && assignment.collectionPosition === collectionPosition;
52908
- if (target) {
52909
- if (assignment.previousParticipantId) {
52910
- previousParticipantIds.push(assignment.previousParticipantId);
52911
- }
52912
- assignmentsRemoved.push({
52913
- participantId: teamCompetitor.participantId,
52914
- ...assignment
52915
- });
52916
- }
52917
- return !target;
52918
- });
52919
- return {
52920
- participantId: teamCompetitor.participantId,
52921
- collectionAssignments
52922
- };
52923
- }).filter(Boolean) || [];
52924
- return { modifiedLineUp, assignmentsRemoved, previousParticipantIds };
52925
- }
52926
-
52927
- function assignTieMatchUpParticipantId(params) {
52928
- const matchUpContext = getTieMatchUpContext(params);
52929
- if (matchUpContext.error)
52930
- return matchUpContext;
52931
- const stack = "assignTieMatchUpParticipantId";
52932
- let teamParticipantId = params.teamParticipantId;
52933
- const { tournamentRecord, drawDefinition, participantId, event } = params;
52934
- if (!participantId) {
52935
- return decorateResult({ result: { error: MISSING_PARTICIPANT_ID }, stack });
52936
- }
52937
- if (params.sideNumber && ![1, 2].includes(params.sideNumber)) {
52938
- return decorateResult({ result: { error: INVALID_SIDE_NUMBER }, stack });
52939
- }
52940
- const {
52941
- inContextDualMatchUp,
52942
- inContextTieMatchUp,
52943
- relevantAssignments,
52944
- collectionPosition,
52945
- teamParticipants,
52946
- collectionId,
52947
- matchUpType,
52948
- dualMatchUp,
52949
- tieFormat
52950
- } = matchUpContext;
52951
- const allTieIndividualParticipantIds = inContextTieMatchUp?.sides?.flatMap(
52952
- (side) => side.participant?.individualParticipantIds || side.participant?.participantId || []
52953
- );
52954
- if (allTieIndividualParticipantIds?.includes(participantId)) {
52955
- return decorateResult({ result: { ...SUCCESS }, stack });
52956
- }
52957
- teamParticipantId = teamParticipantId || params.sideNumber && inContextDualMatchUp?.sides?.find(
52958
- (side) => side.sideNumber === params.sideNumber
52959
- )?.participantId;
52960
- const {
52961
- tournamentParticipants: [participantToAssign]
52962
- } = getTournamentParticipants({
52963
- tournamentRecord,
52964
- participantFilters: {
52965
- participantIds: [participantId]
52966
- }
52967
- });
52968
- if (!participantToAssign) {
52969
- return decorateResult({ result: { error: PARTICIPANT_NOT_FOUND }, stack });
52970
- }
52971
- const { appliedPolicies } = getAppliedPolicies({
52972
- tournamentRecord,
52973
- drawDefinition,
52974
- event
52975
- });
52976
- const matchUpActionsPolicy = params.policyDefinitions?.[POLICY_TYPE_MATCHUP_ACTIONS] || appliedPolicies?.[POLICY_TYPE_MATCHUP_ACTIONS] || POLICY_MATCHUP_ACTIONS_DEFAULT[POLICY_TYPE_MATCHUP_ACTIONS];
52977
- if (matchUpActionsPolicy?.participants?.enforceGender && [MALE, FEMALE].includes(inContextTieMatchUp?.gender) && inContextTieMatchUp?.gender !== participantToAssign.person?.sex) {
52978
- return { error: INVALID_PARTICIPANT, info: "Gender mismatch" };
52979
- }
52980
- const { individualParticipantIds, participantType } = participantToAssign;
52981
- if (matchUpType === SINGLES$1 && participantType !== INDIVIDUAL) {
52982
- return { error: INVALID_PARTICIPANT_TYPE };
52983
- }
52984
- const relevantParticipantIds = participantType === INDIVIDUAL ? [participantId] : individualParticipantIds;
52985
- const participantTeam = teamParticipantId && teamParticipants?.find(
52986
- ({ participantId: participantId2 }) => participantId2 === teamParticipantId
52987
- ) || teamParticipants?.find(
52988
- ({ individualParticipantIds: individualParticipantIds2 }) => overlap(relevantParticipantIds, individualParticipantIds2)
52989
- );
52990
- if (!participantTeam) {
52991
- return { error: TEAM_NOT_FOUND };
52992
- }
52993
- if (!teamParticipantId)
52994
- teamParticipantId = participantTeam.participantId;
52995
- if (!teamParticipantId)
52996
- return { error: PARTICIPANT_NOT_FOUND };
52997
- const teamAssignment = relevantAssignments?.find(
52998
- (assignment) => assignment.participantId === participantTeam?.participantId
52999
- );
53000
- const teamDrawPosition = teamAssignment?.drawPosition;
53001
- const teamSide = inContextTieMatchUp?.sides?.find(
53002
- (side) => side.drawPosition === teamDrawPosition
53003
- );
53004
- const sideNumber = params.sideNumber || teamSide?.sideNumber;
53005
- if (!tieFormat) {
53006
- return { error: MISSING_TIE_FORMAT };
53007
- }
53008
- const collectionDefinition = tieFormat.collectionDefinitions?.find(
53009
- (collectionDefinition2) => collectionDefinition2.collectionId === collectionId
53010
- );
53011
- if (!collectionDefinition)
53012
- return { error: MISSING_COLLECTION_DEFINITION };
53013
- if (!dualMatchUp?.sides?.length) {
53014
- const { extension } = findExtension$2({
53015
- element: drawDefinition,
53016
- name: LINEUPS
53017
- });
53018
- const lineUps = makeDeepCopy(extension?.value || {}, false, true);
53019
- const extractSideDetail = ({
53020
- displaySideNumber,
53021
- drawPosition,
53022
- sideNumber: sideNumber2
53023
- }) => ({ drawPosition, sideNumber: sideNumber2, displaySideNumber });
53024
- if (dualMatchUp) {
53025
- dualMatchUp.sides = inContextDualMatchUp?.sides?.map((side) => {
53026
- const participantId2 = side.participantId;
53027
- return {
53028
- ...extractSideDetail(side),
53029
- lineUp: participantId2 && lineUps[participantId2] || []
53030
- };
53031
- });
53032
- }
53033
- }
53034
- const dualMatchUpSide = dualMatchUp?.sides?.find(
53035
- (side) => side.sideNumber === sideNumber
53036
- );
53037
- const tieMatchUpSide = inContextTieMatchUp?.sides?.find(
53038
- (side) => side.sideNumber === sideNumber
53039
- );
53040
- const lineUp = dualMatchUpSide?.lineUp || getTeamLineUp({
53041
- participantId: teamParticipantId,
53042
- drawDefinition
53043
- })?.lineUp;
53044
- const targetAssignments = lineUp?.filter(
53045
- (participantAssignment) => participantAssignment.collectionAssignments?.find(
53046
- (assignment) => assignment.collectionPosition === collectionPosition && assignment.collectionId === collectionId && !assignment.previousParticipantId
53047
- )
53048
- );
53049
- const assignedParticipantIds = targetAssignments?.map(
53050
- (assignment) => assignment?.participantId
53051
- );
53052
- const participantIds = assignedParticipantIds?.length > 1 && assignedParticipantIds || (participantType === PAIR ? participantToAssign.individualParticipantIds : [participantId]);
53053
- const removeResult = removeCollectionAssignments({
53054
- collectionPosition,
53055
- teamParticipantId,
53056
- dualMatchUpSide,
53057
- drawDefinition,
53058
- participantIds,
53059
- collectionId
53060
- });
53061
- if (removeResult.error)
53062
- return decorateResult({ result: removeResult, stack });
53063
- const { modifiedLineUp } = removeResult;
53064
- let deleteParticipantId;
53065
- if (matchUpType === DOUBLES$1) {
53066
- if (participantType !== PAIR) {
53067
- let result = updateLineUp({
53068
- collectionPosition,
53069
- teamParticipantId,
53070
- drawDefinition,
53071
- modifiedLineUp,
53072
- participantId,
53073
- collectionId,
53074
- tieFormat
53075
- });
53076
- if (result?.error)
53077
- return decorateResult({ result, stack });
53078
- result = addParticipantId2Pair({
53079
- side: tieMatchUpSide
53080
- });
53081
- if (result.error)
53082
- return result;
53083
- deleteParticipantId = result.deleteParticipantId;
53084
- if (dualMatchUpSide)
53085
- dualMatchUpSide.lineUp = modifiedLineUp;
53086
- if (dualMatchUp) {
53087
- modifyMatchUpNotice({
53088
- tournamentId: tournamentRecord?.tournamentId,
53089
- matchUp: dualMatchUp,
53090
- context: stack,
53091
- drawDefinition
53092
- });
53093
- }
53094
- } else if (participantType === PAIR) {
53095
- for (const participantId2 of participantIds) {
53096
- updateLineUp({
53097
- collectionPosition,
53098
- teamParticipantId,
53099
- drawDefinition,
53100
- modifiedLineUp,
53101
- participantId: participantId2,
53102
- collectionId,
53103
- tieFormat
53104
- });
53105
- }
53106
- }
53107
- } else {
53108
- const result = updateLineUp({
53109
- collectionPosition,
53110
- teamParticipantId,
53111
- drawDefinition,
53112
- modifiedLineUp,
53113
- participantId,
53114
- collectionId,
53115
- tieFormat
53116
- });
53117
- if (result?.error)
53118
- return result;
53119
- }
53120
- if (dualMatchUpSide)
53121
- dualMatchUpSide.lineUp = modifiedLineUp;
53122
- if (dualMatchUp)
53123
- modifyMatchUpNotice({
53124
- tournamentId: tournamentRecord?.tournamentId,
53125
- matchUp: dualMatchUp,
53126
- context: stack,
53127
- drawDefinition
53128
- });
53129
- if (deleteParticipantId) {
53130
- const { error } = deleteParticipants({
53131
- participantIds: [deleteParticipantId],
53132
- tournamentRecord
53133
- });
53134
- if (error)
53135
- console.log("cleanup");
53136
- }
53137
- return { ...SUCCESS, modifiedLineUp };
53138
- function addParticipantId2Pair({ side }) {
53139
- let deleteParticipantId2;
53140
- if (!side.participant) {
53141
- const newPairParticipant = {
53142
- individualParticipantIds: [participantId],
53143
- participantRole: COMPETITOR,
53144
- participantType: PAIR
53145
- };
53146
- const result = addParticipant$1({
53147
- participant: newPairParticipant,
53148
- pairOverride: true,
53149
- tournamentRecord
53150
- });
53151
- if (result.error)
53152
- return result;
53153
- } else {
53154
- const individualParticipantIds2 = side.participant.individualParticipantIds || [];
53155
- const sideParticipantsCount = individualParticipantIds2.filter(Boolean).length;
53156
- if (sideParticipantsCount === 1) {
53157
- const { participant } = getPairedParticipant({
53158
- participantIds: individualParticipantIds2,
53159
- tournamentRecord
53160
- });
53161
- individualParticipantIds2.push(participantId);
53162
- const { participant: existingParticipant } = getPairedParticipant({
53163
- participantIds: individualParticipantIds2,
53164
- tournamentRecord
53165
- });
53166
- if (!existingParticipant && participant) {
53167
- participant.individualParticipantIds = individualParticipantIds2;
53168
- const result = modifyParticipant({
53169
- pairOverride: true,
53170
- tournamentRecord,
53171
- participant
53172
- });
53173
- if (result.error)
53174
- return result;
53175
- } else {
53176
- deleteParticipantId2 = participant?.participantId;
53177
- }
53178
- }
53179
- }
53180
- return { ...SUCCESS, deleteParticipantId: deleteParticipantId2 };
53181
- }
53182
- }
53183
- function updateLineUp({
53184
- collectionPosition,
53185
- teamParticipantId,
53186
- drawDefinition,
53187
- modifiedLineUp,
53188
- participantId,
53189
- collectionId,
53190
- tieFormat
53191
- }) {
53192
- const templateTeamLineUp = getTeamLineUp({
53193
- participantId: teamParticipantId,
53194
- drawDefinition
53195
- })?.lineUp;
53196
- const participantCompetitiorProfile = (modifiedLineUp || templateTeamLineUp)?.find((teamCompetitor) => teamCompetitor?.participantId === participantId);
53197
- const newAssignment = { collectionId, collectionPosition };
53198
- if (participantCompetitiorProfile) {
53199
- participantCompetitiorProfile.collectionAssignments.push(newAssignment);
53200
- } else {
53201
- const teamCompetitor = {
53202
- collectionAssignments: [newAssignment],
53203
- participantId
53204
- };
53205
- modifiedLineUp.push(teamCompetitor);
53206
- }
53207
- return updateTeamLineUp({
53208
- participantId: teamParticipantId,
53209
- lineUp: modifiedLineUp,
53210
- drawDefinition,
53211
- tieFormat
53212
- });
53213
- }
53214
-
53215
53909
  function removeTieMatchUpParticipantId(params) {
53216
53910
  const { tournamentRecord, drawDefinition, participantId, event } = params;
53217
53911
  const stack = "removeTieMatchUpParticiapantId";
@@ -55713,150 +56407,6 @@ function setOrderOfFinish(params) {
55713
56407
  return setOrderOfFinish$1(params);
55714
56408
  }
55715
56409
 
55716
- const ASC = "ASC";
55717
- const ASCENDING = "ASC";
55718
- const DESC = "DESC";
55719
- const DESCENDING = "DESC";
55720
- const sortingConstants = { ASC, ASCENDING, DESC, DESCENDING };
55721
-
55722
- function generateLineUps(params) {
55723
- let { tieFormat } = params;
55724
- const {
55725
- useDefaultEventRanking,
55726
- tournamentRecord,
55727
- drawDefinition,
55728
- scaleAccessor,
55729
- // e.g. { scaleType: 'RANKINGS', scaleName: 'U18', accessor: 'wtnRating', sortOrder: 'ASC' }
55730
- singlesOnly,
55731
- // use singles scale for doubles events
55732
- attach,
55733
- // boolean - when true attach LINEUPS extension to drawDefinition and add new PAIR participants (where necessary)
55734
- event
55735
- } = params;
55736
- if (event?.eventType !== TEAM_EVENT)
55737
- return { error: INVALID_EVENT_TYPE };
55738
- if (!tournamentRecord)
55739
- return { error: MISSING_TOURNAMENT_RECORD };
55740
- if (!tieFormat && !drawDefinition)
55741
- return { error: DRAW_DEFINITION_NOT_FOUND };
55742
- tieFormat = tieFormat || resolveTieFormat({ drawDefinition, event })?.tieFormat;
55743
- if (validateTieFormat({ tieFormat }).error)
55744
- return { error: INVALID_TIE_FORMAT };
55745
- if (typeof scaleAccessor !== "object" && !useDefaultEventRanking)
55746
- return { error: INVALID_VALUES, context: { scaleAccessor } };
55747
- const lineUps = {};
55748
- const targetEntries = (drawDefinition?.entries || event.entries).filter(
55749
- (entry) => entry?.entryStatus === DIRECT_ACCEPTANCE
55750
- );
55751
- const participantIds = targetEntries.map(getParticipantId);
55752
- const { participants = [] } = getParticipants$1({
55753
- withIndividualParticipants: true,
55754
- withScaleValues: true,
55755
- tournamentRecord
55756
- });
55757
- const teamParticipants = participants.filter(
55758
- ({ participantId }) => participantIds.includes(participantId)
55759
- );
55760
- const formatScaleType = (type) => type === RANKING$1 ? "rankings" : "ratings";
55761
- const defaultScaleName = event?.category?.categoryName || event?.category?.ageCategoryCode;
55762
- const {
55763
- scaleName = defaultScaleName,
55764
- scaleType = RANKING$1,
55765
- sortOrder,
55766
- accessor
55767
- } = scaleAccessor || {};
55768
- const formattedScaleType = formatScaleType(scaleType);
55769
- const getScaleValue = (individualParticipant, matchUpType) => {
55770
- let matchUpTypeScales = individualParticipant[formattedScaleType]?.[matchUpType];
55771
- if (!matchUpTypeScales && useDefaultEventRanking) {
55772
- matchUpTypeScales = individualParticipant[formattedScaleType]?.[SINGLES_MATCHUP];
55773
- }
55774
- if (Array.isArray(matchUpTypeScales)) {
55775
- const scaleValue = matchUpTypeScales.find(
55776
- (scale) => scale.scaleName === scaleName
55777
- )?.scaleValue;
55778
- if (isNumeric(scaleValue)) {
55779
- return scaleValue;
55780
- } else if (accessor && typeof scaleValue === "object")
55781
- return scaleValue[accessor];
55782
- }
55783
- return 0;
55784
- };
55785
- const sortMethod = (a, b, matchUpType) => {
55786
- const x = sortOrder === DESCENDING ? b : a;
55787
- const y = sortOrder === DESCENDING ? a : b;
55788
- return getScaleValue(x, matchUpType) - getScaleValue(y, matchUpType);
55789
- };
55790
- const singlesScaleSort = (a, b) => sortMethod(a, b, SINGLES_MATCHUP);
55791
- const doublesScaleSort = (a, b) => sortMethod(a, b, DOUBLES_MATCHUP);
55792
- const participantIdPairs = [];
55793
- const collectionDefinitions = tieFormat.collectionDefinitions || [];
55794
- for (const teamParticipant of teamParticipants) {
55795
- const singlesSort = teamParticipant.individualParticipants.sort(singlesScaleSort);
55796
- const doublesSort = singlesOnly ? singlesSort : teamParticipant.individualParticipants.sort(doublesScaleSort);
55797
- const participantAssignments = {};
55798
- for (const collectionDefinition of collectionDefinitions) {
55799
- const collectionParticipantIds = [];
55800
- const { collectionId, matchUpCount, matchUpType, gender } = collectionDefinition;
55801
- const singlesMatchUp = matchUpType === SINGLES_MATCHUP;
55802
- generateRange(0, matchUpCount).forEach((i) => {
55803
- const typeSort = singlesMatchUp ? singlesSort : doublesSort;
55804
- const collectionPosition = i + 1;
55805
- const participantIds2 = [];
55806
- generateRange(0, singlesMatchUp ? 1 : 2).forEach((i2) => {
55807
- const nextParticipantId = typeSort.find((participant) => {
55808
- const targetGender = [MALE, FEMALE].includes(gender) && gender || gender === MIXED && [MALE, FEMALE][i2];
55809
- return (!targetGender || targetGender === participant.person.sex) && !collectionParticipantIds.includes(participant.participantId);
55810
- }).participantId;
55811
- if (nextParticipantId) {
55812
- participantIds2.push(nextParticipantId);
55813
- collectionParticipantIds.push(nextParticipantId);
55814
- if (!participantAssignments[nextParticipantId])
55815
- participantAssignments[nextParticipantId] = [];
55816
- participantAssignments[nextParticipantId].push({
55817
- collectionPosition,
55818
- collectionId
55819
- });
55820
- }
55821
- });
55822
- if (!singlesMatchUp)
55823
- participantIdPairs.push(participantIds2);
55824
- });
55825
- }
55826
- const lineUp = Object.keys(participantAssignments).map((participantId) => ({
55827
- collectionAssignments: participantAssignments[participantId],
55828
- participantId
55829
- }));
55830
- lineUps[teamParticipant.participantId] = lineUp;
55831
- }
55832
- const participantsToAdd = [];
55833
- for (const pairParticipantIds of participantIdPairs) {
55834
- const { participant: existingPairParticipant } = getPairedParticipant({
55835
- tournamentParticipants: participants,
55836
- participantIds: pairParticipantIds
55837
- });
55838
- if (!existingPairParticipant) {
55839
- const newPairParticipant = {
55840
- individualParticipantIds: pairParticipantIds,
55841
- participantRole: COMPETITOR,
55842
- participantType: PAIR
55843
- };
55844
- participantsToAdd.push(newPairParticipant);
55845
- }
55846
- }
55847
- if (attach) {
55848
- while (participantsToAdd.length) {
55849
- addParticipant$1({
55850
- participant: participantsToAdd.pop(),
55851
- tournamentRecord
55852
- });
55853
- }
55854
- const extension = { name: LINEUPS, value: lineUps };
55855
- addExtension$1({ element: drawDefinition, extension });
55856
- }
55857
- return { ...SUCCESS, lineUps, participantsToAdd };
55858
- }
55859
-
55860
56410
  function modifyDrawName({ event, drawId, drawDefinition, drawName }) {
55861
56411
  if (!drawName || typeof drawName !== "string")
55862
56412
  return { error: INVALID_VALUES, drawName };
@@ -57148,6 +57698,12 @@ function enableTieAutoCalc(params) {
57148
57698
  return enableTieAutoCalc$1(params);
57149
57699
  }
57150
57700
 
57701
+ function resetMatchUpLineUps(params) {
57702
+ if (!params.tournamentRecord)
57703
+ return { error: MISSING_TOURNAMENT_RECORD };
57704
+ return resetMatchUpLineUps$1(params);
57705
+ }
57706
+
57151
57707
  const eventGovernor = {
57152
57708
  generateQualifyingStructure,
57153
57709
  attachQualifyingStructure,
@@ -57260,6 +57816,7 @@ const eventGovernor = {
57260
57816
  assignTieMatchUpParticipantId,
57261
57817
  removeTieMatchUpParticipantId,
57262
57818
  replaceTieMatchUpParticipantId,
57819
+ resetMatchUpLineUps,
57263
57820
  updateTeamLineUp,
57264
57821
  validateLineUp,
57265
57822
  getTeamLineUp
@@ -60008,513 +60565,6 @@ function generatePairParticipantName({
60008
60565
  return participantName;
60009
60566
  }
60010
60567
 
60011
- function generateOutcomeFromScoreString(params) {
60012
- const { matchUpFormat, matchUpStatus, winningSide, scoreString } = params;
60013
- if (!scoreString)
60014
- return {
60015
- outcome: {
60016
- ...toBePlayed,
60017
- winningSide,
60018
- matchUpStatus
60019
- }
60020
- };
60021
- if (winningSide && ![1, 2, void 0].includes(winningSide))
60022
- return { error: INVALID_VALUES, winningSide };
60023
- const neutralParsedSets = scoreString && parseScoreString({ scoreString });
60024
- const score = {};
60025
- const winningScoreString = generateScoreString({
60026
- sets: neutralParsedSets,
60027
- matchUpFormat
60028
- });
60029
- const losingScoreString = generateScoreString({
60030
- sets: neutralParsedSets,
60031
- reversed: true,
60032
- matchUpFormat
60033
- });
60034
- if (winningSide === 2) {
60035
- score.scoreStringSide1 = losingScoreString;
60036
- score.scoreStringSide2 = winningScoreString;
60037
- } else {
60038
- score.scoreStringSide1 = winningScoreString;
60039
- score.scoreStringSide2 = losingScoreString;
60040
- }
60041
- score.sets = parseScoreString({ scoreString: score.scoreStringSide1 });
60042
- return definedAttributes({
60043
- outcome: {
60044
- matchUpStatus,
60045
- winningSide,
60046
- score
60047
- }
60048
- });
60049
- }
60050
-
60051
- const defaultStatusProfile = {
60052
- [WALKOVER$2]: 2,
60053
- [DOUBLE_WALKOVER]: 1,
60054
- [DOUBLE_DEFAULT]: 1,
60055
- [RETIRED$1]: 1,
60056
- [DEFAULTED]: 4
60057
- };
60058
- function generateOutcome(params) {
60059
- let { defaultWithScorePercent = 2, winningSide } = params;
60060
- const {
60061
- matchUpStatusProfile = defaultStatusProfile,
60062
- // { matchUpStatusProfile: {} } will always return only { matchUpStatus: COMPLETED }
60063
- matchUpFormat = FORMAT_STANDARD,
60064
- pointsPerMinute = 1,
60065
- sideWeight = 4
60066
- } = params;
60067
- if (!isValid(matchUpFormat))
60068
- return { error: INVALID_MATCHUP_FORMAT };
60069
- if (typeof matchUpStatusProfile !== "object")
60070
- return { error: INVALID_VALUES };
60071
- if (defaultWithScorePercent > 100)
60072
- defaultWithScorePercent = 100;
60073
- if (isNaN(defaultWithScorePercent) || isNaN(pointsPerMinute) || isNaN(sideWeight))
60074
- return { error: INVALID_VALUES };
60075
- const matchUpStatuses = Object.keys(matchUpStatusProfile).filter(
60076
- (matchUpStatus2) => Object.keys(matchUpStatusConstants).includes(matchUpStatus2) && matchUpStatus2 !== COMPLETED$1
60077
- );
60078
- const matchUpStatusTotals = Object.keys(matchUpStatuses).reduce(
60079
- (total, key) => total + matchUpStatusProfile[key],
60080
- 0
60081
- );
60082
- if (matchUpStatusTotals > 100)
60083
- return { error: INVALID_VALUES, matchUpStatusProfile };
60084
- const matchUpStatusMap = matchUpStatuses.reduce(
60085
- (statusMap, matchUpStatus2) => {
60086
- statusMap.pointer = statusMap.pointer + matchUpStatusProfile[matchUpStatus2];
60087
- statusMap.valueMap.push([statusMap.pointer, matchUpStatus2]);
60088
- return statusMap;
60089
- },
60090
- { pointer: 0, valueMap: [] }
60091
- );
60092
- const outcomePointer = randomInt(1, 100);
60093
- const matchUpStatus = (matchUpStatusMap.valueMap.find(
60094
- (item) => outcomePointer <= item[0]
60095
- ) || [100, COMPLETED$1])[1];
60096
- const noScore = { sets: [], scoreStringSide1: "", side2ScoreString: "" };
60097
- if ([WALKOVER$2, DEFAULTED].includes(matchUpStatus)) {
60098
- winningSide = winningSide || randomInt(1, 2);
60099
- const outcome2 = {
60100
- score: noScore,
60101
- winningSide,
60102
- matchUpStatus
60103
- };
60104
- const scoreDefaulted = matchUpStatus === DEFAULTED && randomInt(1, 100) > 100 - defaultWithScorePercent;
60105
- if (!scoreDefaulted)
60106
- return { outcome: outcome2 };
60107
- } else if ([DOUBLE_WALKOVER, DOUBLE_DEFAULT].includes(matchUpStatus)) {
60108
- return { outcome: { score: noScore, matchUpStatus } };
60109
- }
60110
- const parsedFormat = parse(matchUpFormat);
60111
- const { bestOf, setFormat, finalSetFormat } = parsedFormat || {};
60112
- const sets = [];
60113
- const weightedSide = randomInt(0, 1);
60114
- const weightedRange = winningSide ? [winningSide - 1] : [
60115
- ...generateRange(0, sideWeight).map(() => weightedSide),
60116
- 1 - weightedSide
60117
- ];
60118
- const incompleteSet = [RETIRED$1, DEFAULTED, INCOMPLETE, SUSPENDED].includes(
60119
- matchUpStatus
60120
- );
60121
- const incompleteAt = incompleteSet && (randomPop(generateRange(1, bestOf)) || 1);
60122
- let weightedWinningSide;
60123
- for (const setNumber of generateRange(1, (bestOf || 0) + 1)) {
60124
- const isFinalSet = setNumber === bestOf;
60125
- const { set, incomplete, winningSideNumber } = generateSet({
60126
- incomplete: incompleteAt === setNumber,
60127
- matchUpStatus,
60128
- pointsPerMinute,
60129
- setFormat: isFinalSet && finalSetFormat || setFormat,
60130
- setNumber,
60131
- weightedRange
60132
- });
60133
- sets.push(set);
60134
- if (incomplete) {
60135
- weightedWinningSide = winningSideNumber;
60136
- break;
60137
- }
60138
- const analysis2 = analyzeMatchUp({
60139
- matchUp: { score: { sets }, matchUpFormat }
60140
- });
60141
- if (analysis2.calculatedWinningSide)
60142
- break;
60143
- }
60144
- const analysis = analyzeMatchUp({
60145
- matchUp: { score: { sets }, matchUpFormat }
60146
- });
60147
- const matchUpWinningSide = weightedWinningSide ? winningSide || weightedWinningSide : analysis.calculatedWinningSide;
60148
- const { score } = matchUpScore({
60149
- score: { sets },
60150
- winningSide: matchUpWinningSide,
60151
- matchUpStatus
60152
- });
60153
- const outcome = {
60154
- score,
60155
- winningSide: matchUpWinningSide,
60156
- matchUpStatus
60157
- };
60158
- return { outcome };
60159
- }
60160
- function generateSet({
60161
- weightedRange = [0, 1],
60162
- pointsPerMinute,
60163
- matchUpStatus,
60164
- incomplete,
60165
- setFormat,
60166
- setNumber
60167
- }) {
60168
- const set = { setNumber };
60169
- const { setTo, tiebreakFormat, tiebreakAt, tiebreakSet, timed, minutes } = setFormat;
60170
- const weightIndex = randomInt(0, weightedRange.length - 1);
60171
- const reverseScores = weightedRange[weightIndex];
60172
- let winningSideNumber;
60173
- if (timed) {
60174
- const calcPoints = minutes * pointsPerMinute;
60175
- const pointsVariation = Math.round(calcPoints * 0.2);
60176
- const totalPoints = calcPoints + randomPop([1, -1]) * pointsVariation;
60177
- const sidePoints = weightedRandom(totalPoints, 2);
60178
- const scores = [sidePoints, totalPoints - sidePoints];
60179
- if (reverseScores)
60180
- scores.reverse();
60181
- winningSideNumber = weightedRange[weightIndex] + 1;
60182
- let highSide = scores[0] > scores[1] && 1 || scores[1] > scores[0] && 2 || 0;
60183
- if (incomplete) {
60184
- const [side1Score2, side2Score2] = scores;
60185
- Object.assign(set, { side1Score: side1Score2, side2Score: side2Score2 });
60186
- if (completedMatchUpStatuses.includes(matchUpStatus)) {
60187
- return { set, incomplete, winningSideNumber };
60188
- }
60189
- return { set, incomplete };
60190
- }
60191
- if (!highSide)
60192
- scores[randomInt(0, 1)] += 1;
60193
- highSide = scores[0] > scores[1] ? 1 : 2;
60194
- if (highSide !== winningSideNumber)
60195
- scores.reverse();
60196
- const [side1Score, side2Score] = scores;
60197
- Object.assign(set, {
60198
- side1Score,
60199
- side2Score,
60200
- winningSide: winningSideNumber
60201
- });
60202
- return { set };
60203
- } else if (incomplete) {
60204
- set.side1Score = randomInt(0, tiebreakAt);
60205
- set.side2Score = randomInt(0, tiebreakAt);
60206
- if (completedMatchUpStatuses.includes(matchUpStatus)) {
60207
- winningSideNumber = weightedRange[weightIndex] + 1;
60208
- }
60209
- return { set, incomplete, winningSideNumber };
60210
- } else {
60211
- const range = generateRange(1, setTo + 1).map((value) => generateRange(0, setTo + 2 - value).map(() => value)).flat();
60212
- const lowValue = range[randomInt(0, range.length - 1)];
60213
- const scores = setTo && getSetComplement({
60214
- isSide1: true,
60215
- tiebreakAt,
60216
- lowValue,
60217
- setTo
60218
- });
60219
- const isTiebreakSet = !scores;
60220
- const specifiedWinningSide = weightedRange.length === 1 && weightedRange[weightIndex] + 1;
60221
- if (!isTiebreakSet) {
60222
- if (specifiedWinningSide) {
60223
- const highSide = scores[0] > scores[1] ? 1 : 2;
60224
- if (highSide !== specifiedWinningSide)
60225
- scores.reverse();
60226
- } else if (reverseScores) {
60227
- scores.reverse();
60228
- }
60229
- const [side1Score, side2Score] = scores;
60230
- Object.assign(set, { side1Score, side2Score });
60231
- }
60232
- const setAnalysis = analyzeSet({
60233
- matchUpScoringFormat: { setFormat },
60234
- setObject: set
60235
- });
60236
- let tiebreakWinningSide;
60237
- if (setAnalysis.hasTiebreakCondition || isTiebreakSet) {
60238
- const { NoAD: tiebreakNoAd, tiebreakTo } = tiebreakFormat || tiebreakSet || {};
60239
- const range2 = generateRange(1, tiebreakTo + 1).map(
60240
- (value) => generateRange(0, tiebreakTo + 2 - value).map(() => value)
60241
- ).flat();
60242
- const lowValue2 = range2[randomInt(0, range2.length - 1)];
60243
- const scores2 = getTiebreakComplement({
60244
- isSide1: true,
60245
- tiebreakNoAd,
60246
- tiebreakTo,
60247
- lowValue: lowValue2
60248
- });
60249
- if (scores2) {
60250
- if (isTiebreakSet) {
60251
- const highSide = scores2[0] > scores2[1] ? 1 : 2;
60252
- if (specifiedWinningSide) {
60253
- if (highSide !== specifiedWinningSide)
60254
- scores2.reverse();
60255
- } else if (reverseScores) {
60256
- scores2.reverse();
60257
- }
60258
- [set.side1TiebreakScore, set.side2TiebreakScore] = scores2;
60259
- tiebreakWinningSide = scores2[0] > scores2[1] && 1 || scores2[1] > scores2[0] && 2 || void 0;
60260
- } else if (setAnalysis.leadingSide === 2) {
60261
- [set.side1TiebreakScore, set.side2TiebreakScore] = scores2;
60262
- } else {
60263
- [set.side2TiebreakScore, set.side1TiebreakScore] = scores2;
60264
- }
60265
- }
60266
- }
60267
- set.winningSide = setAnalysis.winningSide || setAnalysis.leadingSide || specifiedWinningSide || tiebreakWinningSide;
60268
- }
60269
- return { set };
60270
- }
60271
-
60272
- function completeDrawMatchUps(params) {
60273
- const {
60274
- matchUpStatusProfile,
60275
- // { matchUpStatusProfile: {} } will always return only { matchUpStatus: COMPLETED }
60276
- completeAllMatchUps,
60277
- // qualifyingProfiles, // CONSIDER: allowing completionGoal per structureProfile
60278
- randomWinningSide,
60279
- tournamentRecord,
60280
- completionGoal,
60281
- drawDefinition,
60282
- event
60283
- } = params;
60284
- if (!drawDefinition)
60285
- return { error: MISSING_DRAW_DEFINITION };
60286
- const matchUpFormat = params.matchUpFormat || drawDefinition.matchUpFormat || event?.matchUpFormat;
60287
- const sortedStructures = drawDefinition.structures.slice().sort(structureSort);
60288
- let completedCount = 0;
60289
- const { matchUps: firstRoundDualMatchUps, matchUpsMap } = getAllDrawMatchUps({
60290
- contextFilters: {
60291
- stages: [MAIN, QUALIFYING]
60292
- },
60293
- matchUpFilters: {
60294
- matchUpTypes: [TEAM$2],
60295
- roundNumbers: [1]
60296
- },
60297
- inContext: true,
60298
- drawDefinition
60299
- });
60300
- if (firstRoundDualMatchUps?.length) {
60301
- const categoryName = event?.category?.ageCategoryCode || event?.category?.categoryName;
60302
- if (categoryName) {
60303
- const scaleAccessor = {
60304
- scaleName: categoryName,
60305
- sortOrder: ASCENDING,
60306
- scaleType: RANKING$1
60307
- };
60308
- generateLineUps({
60309
- singlesOnly: true,
60310
- tournamentRecord,
60311
- drawDefinition,
60312
- scaleAccessor,
60313
- attach: true,
60314
- event
60315
- });
60316
- } else {
60317
- const structureId = firstRoundDualMatchUps[0]?.structureId;
60318
- const { positionAssignments } = getPositionAssignments$1({
60319
- drawDefinition,
60320
- structureId
60321
- });
60322
- if (positionAssignments?.length) {
60323
- const { tournamentParticipants: teamParticipants } = getTournamentParticipants({
60324
- participantFilters: { participantTypes: [TEAM$2] },
60325
- tournamentRecord
60326
- });
60327
- const assignParticipants = (dualMatchUp) => {
60328
- const singlesMatchUps = dualMatchUp.tieMatchUps.filter(
60329
- ({ matchUpType }) => matchUpType === SINGLES$1
60330
- );
60331
- const doublesMatchUps = dualMatchUp.tieMatchUps.filter(
60332
- ({ matchUpType }) => matchUpType === DOUBLES$1
60333
- );
60334
- singlesMatchUps.forEach((singlesMatchUp, i) => {
60335
- const tieMatchUpId = singlesMatchUp.matchUpId;
60336
- singlesMatchUp.sides.forEach((side) => {
60337
- const { drawPosition } = side;
60338
- const teamParticipant = teamParticipants?.find(
60339
- (teamParticipant2) => {
60340
- const { participantId } = teamParticipant2;
60341
- const assignment = positionAssignments.find(
60342
- (assignment2) => assignment2.participantId === participantId
60343
- );
60344
- return assignment?.drawPosition === drawPosition;
60345
- }
60346
- );
60347
- if (teamParticipant) {
60348
- const individualParticipantId = teamParticipant.individualParticipantIds[i];
60349
- assignTieMatchUpParticipantId({
60350
- teamParticipantId: teamParticipant.participantId,
60351
- participantId: individualParticipantId,
60352
- tournamentRecord,
60353
- drawDefinition,
60354
- tieMatchUpId,
60355
- event
60356
- });
60357
- }
60358
- });
60359
- });
60360
- doublesMatchUps.forEach((doublesMatchUp, i) => {
60361
- const tieMatchUpId = doublesMatchUp.matchUpId;
60362
- doublesMatchUp.sides.forEach((side) => {
60363
- const { drawPosition } = side;
60364
- const teamParticipant = teamParticipants?.find(
60365
- (teamParticipant2) => {
60366
- const { participantId } = teamParticipant2;
60367
- const assignment = positionAssignments.find(
60368
- (assignment2) => assignment2.participantId === participantId
60369
- );
60370
- return assignment?.drawPosition === drawPosition;
60371
- }
60372
- );
60373
- if (teamParticipant) {
60374
- const individualParticipantIds = teamParticipant.individualParticipantIds.slice(
60375
- i * 2,
60376
- i * 2 + 2
60377
- );
60378
- individualParticipantIds.forEach((individualParticipantId) => {
60379
- assignTieMatchUpParticipantId({
60380
- teamParticipantId: teamParticipant.participantId,
60381
- participantId: individualParticipantId,
60382
- tournamentRecord,
60383
- drawDefinition,
60384
- tieMatchUpId,
60385
- event
60386
- });
60387
- });
60388
- }
60389
- });
60390
- });
60391
- };
60392
- firstRoundDualMatchUps.forEach(assignParticipants);
60393
- }
60394
- }
60395
- }
60396
- const scoreString = typeof completeAllMatchUps === "string" && completeAllMatchUps;
60397
- const matchUpStatus = scoreString && COMPLETED$1;
60398
- for (const structure of sortedStructures) {
60399
- if (completedCount >= completionGoal)
60400
- break;
60401
- const { matchUps } = getAllStructureMatchUps({
60402
- matchUpFilters: { matchUpTypes: [DOUBLES$1, SINGLES$1] },
60403
- afterRecoveryTimes: false,
60404
- tournamentRecord,
60405
- inContext: true,
60406
- drawDefinition,
60407
- matchUpsMap,
60408
- structure,
60409
- event
60410
- });
60411
- const sortedMatchUpIds = matchUps.filter(({ winningSide }) => !winningSide).sort(matchUpSort).map(getMatchUpId);
60412
- for (const matchUpId of sortedMatchUpIds) {
60413
- if (!isNaN(completionGoal) && completedCount >= completionGoal)
60414
- break;
60415
- const { matchUps: matchUps2 } = getAllStructureMatchUps({
60416
- matchUpFilters: { matchUpTypes: [DOUBLES$1, SINGLES$1] },
60417
- afterRecoveryTimes: false,
60418
- tournamentRecord,
60419
- inContext: true,
60420
- drawDefinition,
60421
- matchUpsMap,
60422
- structure,
60423
- event
60424
- });
60425
- const targetMatchUp = matchUps2.find(
60426
- (matchUp) => matchUp.matchUpId === matchUpId
60427
- );
60428
- const isDoubleExit = [DOUBLE_WALKOVER, DOUBLE_DEFAULT].includes(
60429
- targetMatchUp.matchUpStatus
60430
- );
60431
- if (targetMatchUp?.readyToScore && !isDoubleExit) {
60432
- const result = smartComplete({
60433
- winningSide: !randomWinningSide && 1,
60434
- matchUpStatusProfile,
60435
- tournamentRecord,
60436
- drawDefinition,
60437
- targetMatchUp,
60438
- matchUpFormat,
60439
- matchUpStatus,
60440
- scoreString,
60441
- event
60442
- });
60443
- if (result?.error)
60444
- return result;
60445
- completedCount += 1;
60446
- }
60447
- }
60448
- }
60449
- return { ...SUCCESS, completedCount };
60450
- }
60451
- function completeDrawMatchUp(params) {
60452
- const {
60453
- matchUpStatusCodes,
60454
- policyDefinitions,
60455
- tournamentRecord,
60456
- drawDefinition,
60457
- targetMatchUp,
60458
- matchUpStatus,
60459
- matchUpFormat,
60460
- scoreString,
60461
- winningSide,
60462
- event
60463
- } = params;
60464
- if (!targetMatchUp || targetMatchUp.matchUpStatus === BYE) {
60465
- return;
60466
- }
60467
- const { matchUpId } = targetMatchUp || {};
60468
- const { outcome } = generateOutcomeFromScoreString({
60469
- matchUpFormat,
60470
- matchUpStatus,
60471
- scoreString,
60472
- winningSide
60473
- });
60474
- if (matchUpStatusCodes)
60475
- outcome.matchUpStatusCodes = matchUpStatusCodes;
60476
- return setMatchUpStatus$1({
60477
- tournamentRecord,
60478
- policyDefinitions,
60479
- drawDefinition,
60480
- matchUpFormat,
60481
- matchUpId,
60482
- outcome,
60483
- event
60484
- });
60485
- }
60486
- function smartComplete(params) {
60487
- const {
60488
- matchUpStatusProfile = {},
60489
- tournamentRecord,
60490
- policyDefinitions,
60491
- drawDefinition,
60492
- matchUpStatus,
60493
- matchUpFormat,
60494
- targetMatchUp,
60495
- scoreString,
60496
- winningSide,
60497
- event
60498
- } = params;
60499
- if (scoreString || matchUpStatus)
60500
- return completeDrawMatchUp(params);
60501
- const { matchUpId } = targetMatchUp || {};
60502
- const { outcome } = generateOutcome({
60503
- matchUpStatusProfile,
60504
- matchUpFormat,
60505
- winningSide
60506
- });
60507
- return setMatchUpStatus$1({
60508
- policyDefinitions,
60509
- tournamentRecord,
60510
- drawDefinition,
60511
- matchUpFormat,
60512
- matchUpId,
60513
- outcome,
60514
- event
60515
- });
60516
- }
60517
-
60518
60568
  function generateFlightDrawDefinitions({
60519
60569
  matchUpStatusProfile,
60520
60570
  completeAllMatchUps,
@@ -62513,7 +62563,6 @@ const mocksGovernor = {
62513
62563
  generateOutcomeFromScoreString,
62514
62564
  generateTournamentRecord,
62515
62565
  generateEventWithDraw,
62516
- completeDrawMatchUps,
62517
62566
  generateParticipants,
62518
62567
  parseScoreString,
62519
62568
  generateOutcome,