tods-competition-factory 2.2.33 → 2.2.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
5
  function factoryVersion() {
6
- return '2.2.33';
6
+ return '2.2.35';
7
7
  }
8
8
 
9
9
  const SINGLES_MATCHUP = 'SINGLES';
@@ -2206,11 +2206,11 @@ function isValidMatchUpFormat({ matchUpFormat }) {
2206
2206
  if (!isString(matchUpFormat) || matchUpFormat === '')
2207
2207
  return false;
2208
2208
  const parsedFormat = parse(matchUpFormat);
2209
- const setParts = matchUpFormat.match(/-S:([1-9])+\/TB(\d{1,2})@?([1-9]?)*/);
2209
+ const setParts = /-S:([1-9])+\/TB(\d{1,2})@?([1-9]?)/.exec(matchUpFormat);
2210
2210
  const setsTo = setParts?.[1];
2211
2211
  const tiebreakTo = setParts?.[2];
2212
2212
  const tiebreakAt = setParts?.[3];
2213
- const finalSetParts = matchUpFormat.match(/-F:([1-9])+\/TB(\d{1,2})@?([1-9]?)*/);
2213
+ const finalSetParts = /-F:([1-9])+\/TB(\d{1,2})@?([1-9]?)/.exec(matchUpFormat);
2214
2214
  const finalSetTo = finalSetParts?.[1];
2215
2215
  const finalSetTiebreakTo = finalSetParts?.[2];
2216
2216
  const finalTiebreakAt = finalSetParts?.[3];
@@ -10372,6 +10372,10 @@ function addMatchUpContext({ scheduleVisibilityFilters, sourceDrawPositionRanges
10372
10372
  else if (setFormat?.tiebreakSet || setFormat?.timed) {
10373
10373
  set.tiebreakSet = true;
10374
10374
  }
10375
+ if (set.tiebreakSet && [1, 2].includes(set.winningSide)) {
10376
+ set.side1Score = set.winningSide === 1 ? 1 : 0;
10377
+ set.side2Score = set.winningSide === 2 ? 1 : 0;
10378
+ }
10375
10379
  return set;
10376
10380
  });
10377
10381
  }
@@ -10442,11 +10446,11 @@ function addMatchUpContext({ scheduleVisibilityFilters, sourceDrawPositionRanges
10442
10446
  participant.entryStage = entryStage;
10443
10447
  }
10444
10448
  }
10445
- if (hydrateParticipants !== false) {
10446
- Object.assign(side, { participant });
10449
+ if (hydrateParticipants === false) {
10450
+ Object.assign(side, { participant: { entryStage, entryStatus } });
10447
10451
  }
10448
10452
  else {
10449
- Object.assign(side, { participant: { entryStage, entryStatus } });
10453
+ Object.assign(side, { participant });
10450
10454
  }
10451
10455
  }
10452
10456
  }
@@ -10554,7 +10558,7 @@ function addMatchUpContext({ scheduleVisibilityFilters, sourceDrawPositionRanges
10554
10558
  });
10555
10559
  });
10556
10560
  }
10557
- const hasParticipants = matchUpWithContext.sides && matchUpWithContext.sides.filter((side) => side?.participantId).length === 2;
10561
+ const hasParticipants = matchUpWithContext.sides?.filter((side) => side?.participantId).length === 2;
10558
10562
  const hasNoWinner = !matchUpWithContext.winningSide;
10559
10563
  const readyToScore = scoringActive && hasParticipants && hasNoWinner;
10560
10564
  Object.assign(matchUpWithContext, { readyToScore, hasContext: true });
@@ -12359,9 +12363,7 @@ function assignDrawPositionBye({ provisionalPositioning, isPositionAction, tourn
12359
12363
  ({ structureId } = structure);
12360
12364
  const stack = 'assignDrawPositionBye';
12361
12365
  pushGlobalLog({ method: stack, color: 'cyan', drawPosition });
12362
- if (!matchUpsMap) {
12363
- matchUpsMap = getMatchUpsMap({ drawDefinition });
12364
- }
12366
+ matchUpsMap ??= getMatchUpsMap({ drawDefinition });
12365
12367
  const { positionAssignments } = getPositionAssignments$1({ structure });
12366
12368
  const { activeDrawPositions } = getStructureDrawPositionProfiles({
12367
12369
  drawDefinition,
@@ -12371,7 +12373,8 @@ function assignDrawPositionBye({ provisionalPositioning, isPositionAction, tourn
12371
12373
  if (currentAssignment?.bye) {
12372
12374
  return { ...SUCCESS };
12373
12375
  }
12374
- const hasPropagatedStatus = !!(loserMatchUp && matchUpsMap.drawMatchUps.find((m) => m.loserMatchUpId === loserMatchUp?.matchUpId && isExit(m.matchUpStatus)));
12376
+ const hasPropagatedStatus = !!(loserMatchUp &&
12377
+ matchUpsMap.drawMatchUps.find((m) => m.loserMatchUpId === loserMatchUp?.matchUpId && isExit(m.matchUpStatus)));
12375
12378
  const drawPositionIsActive = activeDrawPositions?.includes(drawPosition);
12376
12379
  if (drawPositionIsActive && !hasPropagatedStatus) {
12377
12380
  return { error: DRAW_POSITION_ACTIVE };
@@ -16727,9 +16730,9 @@ function assignMatchUpDrawPosition({ inContextDrawMatchUps, sourceMatchUpStatus,
16727
16730
  inContextDrawMatchUps,
16728
16731
  drawPosition,
16729
16732
  matchUpId,
16730
- }))
16731
- || (isPropagatedExit && matchUp.winningSide)
16732
- || undefined;
16733
+ })) ||
16734
+ (isPropagatedExit && matchUp.winningSide) ||
16735
+ undefined;
16733
16736
  if (matchUp?.matchUpStatusCodes) {
16734
16737
  updateMatchUpStatusCodes({
16735
16738
  inContextDrawMatchUps,
@@ -22085,7 +22088,7 @@ function countGames({ matchUpFormat = FORMAT_STANDARD, winningSide: matchUpWinni
22085
22088
  const based = parsedMatchUpFormat?.[whichFormat]?.based;
22086
22089
  const isTiebreakSet = parsedMatchUpFormat?.[whichFormat].tiebreakSet;
22087
22090
  const { side1Score, side2Score } = set;
22088
- if (isGamesBased(based)) {
22091
+ if (isGamesBased(based) && !isTiebreakSet) {
22089
22092
  gamesTally[0].push(ensureInt(side1Score || 0));
22090
22093
  gamesTally[1].push(ensureInt(side2Score || 0));
22091
22094
  }
@@ -22560,6 +22563,42 @@ function processOutcome$1({ winningParticipantId, losingParticipantId, participa
22560
22563
  }
22561
22564
  }
22562
22565
 
22566
+ function addExplanation(step, participants, readable, floatSort) {
22567
+ if (!step.groups)
22568
+ return;
22569
+ Object.keys(step.groups)
22570
+ .sort(floatSort)
22571
+ .forEach((key) => {
22572
+ const participantNames = step.groups[key].map((participantId) => participants[participantId]).join(', ');
22573
+ const explanation = `${key} ${step.attribute}: ${participantNames}`;
22574
+ readable.push(explanation);
22575
+ });
22576
+ }
22577
+ function processReportStep(step, i, participants, readable) {
22578
+ if (step.excludedDirectives?.length) {
22579
+ const attributes = step.excludedDirectives.map(({ attribute }) => attribute).join(', ');
22580
+ const note = `${attributes.length} directives were excluded due to participants limit}`;
22581
+ readable.push(note);
22582
+ const excluded = `Excluded: ${attributes}`;
22583
+ readable.push(excluded);
22584
+ }
22585
+ else {
22586
+ const floatSort = (a, b) => Number.parseFloat(step.reversed ? a : b) - Number.parseFloat(step.reversed ? b : a);
22587
+ const participantsCount = step.groups
22588
+ ? Object.values(step.groups).flat(Infinity).length
22589
+ : (step.participantIds?.length ?? 0);
22590
+ const reversed = step.reversed ? ' in reverse order' : '';
22591
+ const action = step.groups ? 'grouped' : 'separated';
22592
+ const description = `Step ${i + 1}: ${participantsCount} particiants were ${action}${reversed} by ${step.attribute}`;
22593
+ readable.push(description);
22594
+ if (step.idsFilter) {
22595
+ const note = `${step.attribute} was calculated considering ONLY TIED PARTICIPANTS`;
22596
+ readable.push(note);
22597
+ }
22598
+ addExplanation(step, participants, readable, floatSort);
22599
+ }
22600
+ readable.push('----------------------');
22601
+ }
22563
22602
  function getTallyReport({ matchUps, order, report }) {
22564
22603
  const participants = {};
22565
22604
  matchUps.forEach(({ sides }) => {
@@ -22572,41 +22611,7 @@ function getTallyReport({ matchUps, order, report }) {
22572
22611
  const readable = [];
22573
22612
  if (Array.isArray(report)) {
22574
22613
  report.forEach((step, i) => {
22575
- if (step.excludedDirectives?.length) {
22576
- const attributes = step.excludedDirectives.map(({ attribute }) => attribute).join(', ');
22577
- const note = `${attributes.length} directives were excluded due to participants limit}`;
22578
- readable.push(note);
22579
- const excluded = `Excluded: ${attributes}`;
22580
- readable.push(excluded);
22581
- }
22582
- else {
22583
- const floatSort = (a, b) => parseFloat(step.reversed ? a : b) - parseFloat(step.reversed ? b : a);
22584
- const participantsCount = step.groups
22585
- ? Object.values(step.groups).flat(Infinity).length
22586
- : (step.participantIds?.length ?? 0);
22587
- const getExplanation = (step) => {
22588
- step.groups &&
22589
- Object.keys(step.groups)
22590
- .sort(floatSort)
22591
- .forEach((key) => {
22592
- const participantNames = step.groups[key]
22593
- .map((participantId) => participants[participantId])
22594
- .join(', ');
22595
- const explanation = `${key} ${step.attribute}: ${participantNames}`;
22596
- readable.push(explanation);
22597
- });
22598
- };
22599
- const reversed = step.reversed ? ' in reverse order' : '';
22600
- const action = step.groups ? 'grouped' : 'separated';
22601
- const description = `Step ${i + 1}: ${participantsCount} particiants were ${action}${reversed} by ${step.attribute}`;
22602
- readable.push(description);
22603
- if (step.idsFilter) {
22604
- const note = `${step.attribute} was calculated considering ONLY TIED PARTICIPANTS`;
22605
- readable.push(note);
22606
- }
22607
- getExplanation(step);
22608
- }
22609
- readable.push('----------------------');
22614
+ processReportStep(step, i, participants, readable);
22610
22615
  });
22611
22616
  }
22612
22617
  readable.push('Final Order:');
@@ -29082,7 +29087,10 @@ function generateScoreString(params) {
29082
29087
  const t1 = side1TiebreakScore || (isNumeric(side1TiebreakScore) || (tbscores && autoComplete) ? 0 : '');
29083
29088
  const t2 = side2TiebreakScore || (isNumeric(side2TiebreakScore) || (tbscores && autoComplete) ? 0 : '');
29084
29089
  if (isTiebreakSet) {
29085
- const tiebreakScore = reverseScores ? [t2, t1] : [t1, t2];
29090
+ const useGameScores = hasGameScores(currentSet) && !tbscores;
29091
+ const score1 = useGameScores ? side1Score : t1;
29092
+ const score2 = useGameScores ? side2Score : t2;
29093
+ const tiebreakScore = reverseScores ? [score2, score1] : [score1, score2];
29086
29094
  return `[${tiebreakScore.join('-')}]`;
29087
29095
  }
29088
29096
  const lowTiebreakScore = tbscores ? Math.min(t1, t2) : '';
@@ -31902,6 +31910,29 @@ function handleRetired({ score, profile, applied }) {
31902
31910
  }
31903
31911
  return { score };
31904
31912
  }
31913
+ function handleDefaulted({ score, profile, applied }) {
31914
+ score = score?.toString().toLowerCase();
31915
+ const re = /^(.*\d+.*)(def|defaulted)+[A-Za-z ]*$/;
31916
+ if (re.test(score)) {
31917
+ const [leading] = score.match(re).slice(1);
31918
+ applied.push('handleDefaulted');
31919
+ return { score: leading.trim(), matchUpStatus: 'defaulted', applied };
31920
+ }
31921
+ const providerDefaulted = profile?.matchUpStatuses?.defaulted;
31922
+ const additionalDefaulted = Array.isArray(providerDefaulted)
31923
+ ? providerDefaulted
31924
+ : [providerDefaulted].filter(Boolean);
31925
+ const defaulted = ['dft', ...additionalDefaulted].find((def) => score?.endsWith(def));
31926
+ if (defaulted) {
31927
+ applied.push('handleDefaulted');
31928
+ return {
31929
+ matchUpStatus: 'defaulted',
31930
+ score: score?.replace(defaulted, '').trim(),
31931
+ applied,
31932
+ };
31933
+ }
31934
+ return { score };
31935
+ }
31905
31936
  function removeDanglingBits({ score, attributes }) {
31906
31937
  if (score.endsWith(' am') || score.endsWith(' pm'))
31907
31938
  score = '';
@@ -32001,6 +32032,7 @@ const transforms = {
32001
32032
  matchKnownPatterns: matchKnownPatterns,
32002
32033
  removeDanglingBits: removeDanglingBits,
32003
32034
  removeErroneous: removeErroneous,
32035
+ handleDefaulted: handleDefaulted,
32004
32036
  handleWalkover: handleWalkover,
32005
32037
  properTiebreak: properTiebreak,
32006
32038
  handleNumeric: handleNumeric,
@@ -32019,6 +32051,7 @@ const processingOrder = [
32019
32051
  'handleNumeric',
32020
32052
  'handleWalkover',
32021
32053
  'handleRetired',
32054
+ 'handleDefaulted',
32022
32055
  'replaceOh',
32023
32056
  'stringScore',
32024
32057
  'punctuationAdjustments',
@@ -32114,6 +32147,179 @@ var help = {
32114
32147
  tidyScore: tidyScore
32115
32148
  };
32116
32149
 
32150
+ function validateSetScore(set, matchUpFormat, isDecidingSet, allowIncomplete) {
32151
+ if (!matchUpFormat)
32152
+ return { isValid: true };
32153
+ const parsed = parse(matchUpFormat);
32154
+ if (!parsed)
32155
+ return { isValid: true };
32156
+ const setFormat = isDecidingSet && parsed.finalSetFormat ? parsed.finalSetFormat : parsed.setFormat;
32157
+ if (!setFormat)
32158
+ return { isValid: true };
32159
+ const { setTo, tiebreakAt, tiebreakFormat, tiebreakSet } = setFormat;
32160
+ const tiebreakSetTo = tiebreakSet?.tiebreakTo;
32161
+ const isTiebreakOnlyFormat = !!tiebreakSetTo && !setTo;
32162
+ const side1Score = set.side1Score || 0;
32163
+ const side2Score = set.side2Score || 0;
32164
+ const side1TiebreakScore = set.side1TiebreakScore;
32165
+ const side2TiebreakScore = set.side2TiebreakScore;
32166
+ const winnerScore = Math.max(side1Score, side2Score);
32167
+ const loserScore = Math.min(side1Score, side2Score);
32168
+ const scoreDiff = winnerScore - loserScore;
32169
+ if (isTiebreakOnlyFormat) {
32170
+ if (allowIncomplete) {
32171
+ return { isValid: true };
32172
+ }
32173
+ if (side1Score === 0 && side2Score === 0) {
32174
+ return { isValid: false, error: 'Tiebreak-only set requires both scores' };
32175
+ }
32176
+ if (winnerScore < tiebreakSetTo) {
32177
+ return {
32178
+ isValid: false,
32179
+ error: `Tiebreak-only set winner must reach at least ${tiebreakSetTo}, got ${winnerScore}`,
32180
+ };
32181
+ }
32182
+ if (loserScore < tiebreakSetTo - 1) {
32183
+ return {
32184
+ isValid: false,
32185
+ error: `Tiebreak-only set loser must be at least ${tiebreakSetTo - 1} when winner exceeds ${tiebreakSetTo}, got ${loserScore}`,
32186
+ };
32187
+ }
32188
+ if (scoreDiff !== 2) {
32189
+ return {
32190
+ isValid: false,
32191
+ error: `Tiebreak-only set must be won by exactly 2 points, got ${winnerScore}-${loserScore}`,
32192
+ };
32193
+ }
32194
+ return { isValid: true };
32195
+ }
32196
+ const hasExplicitTiebreak = side1TiebreakScore !== undefined || side2TiebreakScore !== undefined;
32197
+ const isImplicitTiebreak = setTo && winnerScore === setTo + 1 && loserScore === setTo;
32198
+ const isLikelyTiebreak = tiebreakAt && winnerScore === tiebreakAt - 1 && loserScore === tiebreakAt - 2;
32199
+ const hasTiebreak = hasExplicitTiebreak || isImplicitTiebreak || isLikelyTiebreak;
32200
+ if (hasTiebreak) {
32201
+ if (setTo && !isLikelyTiebreak) {
32202
+ if (winnerScore !== setTo + 1) {
32203
+ return {
32204
+ isValid: false,
32205
+ error: `Tiebreak set winner must have ${setTo + 1} games, got ${winnerScore}`,
32206
+ };
32207
+ }
32208
+ if (loserScore !== setTo) {
32209
+ return {
32210
+ isValid: false,
32211
+ error: `Tiebreak set loser must have ${setTo} games when tied, got ${loserScore}`,
32212
+ };
32213
+ }
32214
+ }
32215
+ if (hasExplicitTiebreak && tiebreakFormat) {
32216
+ const tbWinnerScore = Math.max(side1TiebreakScore || 0, side2TiebreakScore || 0);
32217
+ const tbLoserScore = Math.min(side1TiebreakScore || 0, side2TiebreakScore || 0);
32218
+ const tbDiff = tbWinnerScore - tbLoserScore;
32219
+ const tbTo = tiebreakFormat.tiebreakTo || 7;
32220
+ if (tbWinnerScore < tbTo) {
32221
+ return {
32222
+ isValid: false,
32223
+ error: `Tiebreak winner must reach ${tbTo} points, got ${tbWinnerScore}`,
32224
+ };
32225
+ }
32226
+ if (tbDiff < 2) {
32227
+ return {
32228
+ isValid: false,
32229
+ error: `Tiebreak must be won by 2 points, got ${tbWinnerScore}-${tbLoserScore}`,
32230
+ };
32231
+ }
32232
+ if (tbLoserScore >= tbTo - 1 && tbDiff > 2) {
32233
+ return {
32234
+ isValid: false,
32235
+ error: `Tiebreak score ${tbWinnerScore}-${tbLoserScore} is invalid`,
32236
+ };
32237
+ }
32238
+ }
32239
+ }
32240
+ else {
32241
+ if (setTo && tiebreakAt) {
32242
+ if (side1Score === setTo + 1 && side2Score < setTo - 1) {
32243
+ return {
32244
+ isValid: false,
32245
+ error: `With tiebreak format, if side 1 has ${setTo + 1} games, side 2 must be at least ${setTo - 1}, got ${side2Score}`,
32246
+ };
32247
+ }
32248
+ if (side2Score === setTo + 1 && side1Score < setTo - 1) {
32249
+ return {
32250
+ isValid: false,
32251
+ error: `With tiebreak format, if side 2 has ${setTo + 1} games, side 1 must be at least ${setTo - 1}, got ${side1Score}`,
32252
+ };
32253
+ }
32254
+ }
32255
+ if (allowIncomplete) {
32256
+ if (setTo && (winnerScore > setTo + 10 || loserScore > setTo + 10)) {
32257
+ return {
32258
+ isValid: false,
32259
+ error: `Set score ${winnerScore}-${loserScore} exceeds expected range for ${setTo}-game sets`,
32260
+ };
32261
+ }
32262
+ return { isValid: true };
32263
+ }
32264
+ if (setTo && winnerScore < setTo) {
32265
+ return {
32266
+ isValid: false,
32267
+ error: `Set winner must reach ${setTo} games, got ${winnerScore}`,
32268
+ };
32269
+ }
32270
+ if (scoreDiff < 2) {
32271
+ return {
32272
+ isValid: false,
32273
+ error: `Set must be won by at least 2 games, got ${winnerScore}-${loserScore}`,
32274
+ };
32275
+ }
32276
+ if (tiebreakAt) {
32277
+ if (loserScore >= tiebreakAt) {
32278
+ return {
32279
+ isValid: false,
32280
+ error: `When tied at ${tiebreakAt}-${tiebreakAt}, must play tiebreak. Use format like ${tiebreakAt + 1}-${tiebreakAt}(5)`,
32281
+ };
32282
+ }
32283
+ if (winnerScore > setTo + 1) {
32284
+ return {
32285
+ isValid: false,
32286
+ error: `With tiebreak format, set score cannot exceed ${setTo + 1}-${setTo - 1}. Got ${winnerScore}-${loserScore}`,
32287
+ };
32288
+ }
32289
+ }
32290
+ else {
32291
+ if (winnerScore > setTo + 10) {
32292
+ return {
32293
+ isValid: false,
32294
+ error: `Set score ${winnerScore}-${loserScore} exceeds reasonable limits`,
32295
+ };
32296
+ }
32297
+ }
32298
+ }
32299
+ return { isValid: true };
32300
+ }
32301
+ function validateMatchUpScore(sets, matchUpFormat, matchUpStatus) {
32302
+ if (!sets || sets.length === 0) {
32303
+ return { isValid: true };
32304
+ }
32305
+ const bestOfMatch = matchUpFormat?.match(/SET(\d+)/)?.[1];
32306
+ const bestOfSets = bestOfMatch ? Number.parseInt(bestOfMatch) : 3;
32307
+ const hasIncompleteSet = sets.some((set) => !set.winningSide);
32308
+ const isIrregularEnding = [RETIRED$1, WALKOVER$2, DEFAULTED].includes(matchUpStatus || '');
32309
+ const allowIncomplete = isIrregularEnding || (!matchUpStatus && hasIncompleteSet);
32310
+ for (let i = 0; i < sets.length; i++) {
32311
+ const isDecidingSet = bestOfSets === 1 || i + 1 === bestOfSets;
32312
+ const setValidation = validateSetScore(sets[i], matchUpFormat, isDecidingSet, allowIncomplete);
32313
+ if (!setValidation.isValid) {
32314
+ return {
32315
+ isValid: false,
32316
+ error: `Set ${i + 1}: ${setValidation.error}`,
32317
+ };
32318
+ }
32319
+ }
32320
+ return { isValid: true };
32321
+ }
32322
+
32117
32323
  function analyzeScore({ existingMatchUpStatus, matchUpFormat, matchUpStatus, winningSide, score, }) {
32118
32324
  const sets = score?.sets ?? [];
32119
32325
  const completedSets = sets?.filter((set) => set?.winningSide) || [];
@@ -32126,7 +32332,9 @@ function analyzeScore({ existingMatchUpStatus, matchUpFormat, matchUpStatus, win
32126
32332
  return counts;
32127
32333
  }, [0, 0]);
32128
32334
  const matchUpWinningSideIndex = winningSide ? winningSide - 1 : undefined;
32129
- const matchUpLosingSideIndex = matchUpWinningSideIndex !== undefined ? 1 - matchUpWinningSideIndex : undefined;
32335
+ const matchUpLosingSideIndex = matchUpWinningSideIndex !== undefined && [0, 1].includes(matchUpWinningSideIndex)
32336
+ ? 1 - matchUpWinningSideIndex
32337
+ : undefined;
32130
32338
  const winningSideSetsCount = matchUpWinningSideIndex !== undefined && setsWinCounts[matchUpWinningSideIndex];
32131
32339
  const losingSideSetsCount = matchUpLosingSideIndex !== undefined && setsWinCounts[matchUpLosingSideIndex];
32132
32340
  const matchUpScoringFormat = matchUpFormat ? parse(matchUpFormat) : undefined;
@@ -32289,32 +32497,69 @@ function getHighTiebreakValue(params) {
32289
32497
  return tiebreakTo;
32290
32498
  }
32291
32499
 
32292
- function parseScoreString({ tiebreakTo = 7, scoreString = '' }) {
32500
+ function parseScoreString({ tiebreakTo = 7, scoreString = '', matchUpFormat }) {
32501
+ let isTiebreakOnlyFormat = false;
32502
+ if (matchUpFormat) {
32503
+ try {
32504
+ const parsed = parse(matchUpFormat);
32505
+ const tiebreakSetTo = parsed?.setFormat?.tiebreakSet?.tiebreakTo;
32506
+ const regularSetTo = parsed?.setFormat?.setTo;
32507
+ isTiebreakOnlyFormat = !!tiebreakSetTo && !regularSetTo;
32508
+ }
32509
+ catch (e) {
32510
+ }
32511
+ }
32293
32512
  return scoreString
32294
32513
  ?.split(' ')
32295
32514
  .filter(Boolean)
32296
32515
  .map((set, index) => parseSet({ set, setNumber: index + 1 }));
32297
32516
  function parseSet({ set, setNumber }) {
32298
32517
  const inParentheses = /\(([^)]+)\)/;
32299
- const inBrackets = /\[([^)]+)\]/;
32518
+ const inBrackets = /\[([^\]]+)\]/;
32300
32519
  const tiebreak = inParentheses.exec(set);
32301
- const supertiebreak = inBrackets.exec(set);
32302
- const matchTiebreak = set?.startsWith('[') && supertiebreak && supertiebreak[1].split('-').map((sideScore) => parseInt(sideScore));
32303
- const setString = (tiebreak && set.replace(tiebreak[0], '')) || (supertiebreak && set.replace(supertiebreak[0], '')) || set;
32304
- const setScores = !matchTiebreak && setString.split('-').map((sideScore) => parseInt(sideScore));
32305
- const winningSide = matchTiebreak
32306
- ? (matchTiebreak[0] > matchTiebreak[1] && 1) || (matchTiebreak[0] < matchTiebreak[1] && 2) || undefined
32307
- : (setScores[0] > setScores[1] && 1) || (setScores[0] < setScores[1] && 2) || undefined;
32308
- const setTiebreakLowScore = tiebreak ? tiebreak[1] : undefined;
32309
- const side1TiebreakPerspective = setTiebreakLowScore &&
32310
- getTiebreakComplement({
32311
- lowValue: setTiebreakLowScore,
32312
- isSide1: winningSide === 2,
32313
- tiebreakTo,
32314
- });
32315
- const setTiebreak = side1TiebreakPerspective ?? [];
32316
- const [side1Score, side2Score] = setScores || [];
32317
- const [side1TiebreakScore, side2TiebreakScore] = matchTiebreak || setTiebreak || [];
32520
+ const bracketed = inBrackets.exec(set);
32521
+ const isTiebreakOnlySet = set?.startsWith('[') && bracketed;
32522
+ let side1Score;
32523
+ let side2Score;
32524
+ let side1TiebreakScore;
32525
+ let side2TiebreakScore;
32526
+ let winningSide;
32527
+ if (isTiebreakOnlySet) {
32528
+ const bracketedScores = bracketed[1].split('-').map((score) => parseInt(score));
32529
+ if (isTiebreakOnlyFormat) {
32530
+ side1Score = bracketedScores[0];
32531
+ side2Score = bracketedScores[1];
32532
+ winningSide = (side1Score > side2Score && 1) || (side1Score < side2Score && 2) || undefined;
32533
+ }
32534
+ else {
32535
+ side1TiebreakScore = bracketedScores[0];
32536
+ side2TiebreakScore = bracketedScores[1];
32537
+ winningSide = (side1TiebreakScore > side2TiebreakScore && 1) || (side1TiebreakScore < side2TiebreakScore && 2) || undefined;
32538
+ }
32539
+ }
32540
+ else {
32541
+ const setString = (tiebreak && set.replace(tiebreak[0], '')) || (bracketed && set.replace(bracketed[0], '')) || set;
32542
+ const setScores = setString.split('-').map((score) => parseInt(score));
32543
+ side1Score = setScores[0];
32544
+ side2Score = setScores[1];
32545
+ winningSide = (side1Score > side2Score && 1) || (side1Score < side2Score && 2) || undefined;
32546
+ if (tiebreak) {
32547
+ const setTiebreakLowScore = tiebreak[1];
32548
+ const side1TiebreakPerspective = getTiebreakComplement({
32549
+ lowValue: setTiebreakLowScore,
32550
+ isSide1: winningSide === 2,
32551
+ tiebreakTo,
32552
+ });
32553
+ if (Array.isArray(side1TiebreakPerspective)) {
32554
+ [side1TiebreakScore, side2TiebreakScore] = side1TiebreakPerspective;
32555
+ }
32556
+ }
32557
+ if (bracketed && !isTiebreakOnlySet) {
32558
+ const matchTiebreakScores = bracketed[1].split('-').map((score) => parseInt(score));
32559
+ side1TiebreakScore = matchTiebreakScores[0];
32560
+ side2TiebreakScore = matchTiebreakScores[1];
32561
+ }
32562
+ }
32318
32563
  return {
32319
32564
  side1Score,
32320
32565
  side2Score,
@@ -32596,7 +32841,9 @@ var query$a = {
32596
32841
  getTiebreakComplement: getTiebreakComplement,
32597
32842
  isValidMatchUpFormat: isValidMatchUpFormat,
32598
32843
  parseScoreString: parseScoreString,
32844
+ validateMatchUpScore: validateMatchUpScore,
32599
32845
  validateScore: validateScore,
32846
+ validateSetScore: validateSetScore,
32600
32847
  validateTieFormat: validateTieFormat
32601
32848
  };
32602
32849
 
@@ -32631,7 +32878,9 @@ var scoreGovernor = {
32631
32878
  tidyScore: tidyScore,
32632
32879
  umo: umo,
32633
32880
  undo: undo,
32881
+ validateMatchUpScore: validateMatchUpScore,
32634
32882
  validateScore: validateScore,
32883
+ validateSetScore: validateSetScore,
32635
32884
  validateTieFormat: validateTieFormat
32636
32885
  };
32637
32886
 
@@ -38487,6 +38736,42 @@ function checkDrawTypeIsAllowed(params) {
38487
38736
  return { ...SUCCESS };
38488
38737
  }
38489
38738
 
38739
+ function hydrateRoundNames(params) {
38740
+ const { drawDefinition, appliedPolicies } = params;
38741
+ const roundNamingPolicy = appliedPolicies?.[POLICY_TYPE_ROUND_NAMING];
38742
+ const matchUpsMap = getMatchUpsMap({ drawDefinition });
38743
+ drawDefinition.structures?.forEach((structure) => {
38744
+ const matchUps = getMappedStructureMatchUps({
38745
+ structureId: structure.structureId,
38746
+ matchUpsMap,
38747
+ });
38748
+ const result = getRoundContextProfile({
38749
+ roundNamingPolicy,
38750
+ drawDefinition,
38751
+ structure,
38752
+ matchUps,
38753
+ });
38754
+ const { roundNamingProfile, roundProfile } = result;
38755
+ const structures = structure.structures || [structure];
38756
+ structures.forEach((itemStructure) => {
38757
+ (itemStructure.matchUps ?? []).forEach((matchUp) => {
38758
+ const roundNumber = matchUp?.roundNumber?.toString();
38759
+ if (roundNumber) {
38760
+ const roundName = roundNamingProfile?.[roundNumber]?.roundName;
38761
+ const abbreviatedRoundName = roundNamingProfile?.[roundNumber]?.abbreviatedRoundName;
38762
+ const feedRound = roundProfile?.[roundNumber]?.feedRound;
38763
+ Object.assign(matchUp, {
38764
+ abbreviatedRoundName,
38765
+ feedRound,
38766
+ roundName,
38767
+ });
38768
+ }
38769
+ });
38770
+ });
38771
+ });
38772
+ return { drawDefinition };
38773
+ }
38774
+
38490
38775
  function generateDrawDefinition(params) {
38491
38776
  const { voluntaryConsolation, tournamentRecord, event } = params;
38492
38777
  const stack = 'generateDrawDefinition';
@@ -38561,38 +38846,8 @@ function generateDrawDefinition(params) {
38561
38846
  }
38562
38847
  if (params.hydrateRoundNames) {
38563
38848
  const roundNamingPolicy = appliedPolicies?.[POLICY_TYPE_ROUND_NAMING];
38564
- if (roundNamingPolicy) {
38565
- const matchUpsMap = getMatchUpsMap({ drawDefinition });
38566
- drawDefinition.structures?.forEach((structure) => {
38567
- const matchUps = getMappedStructureMatchUps({
38568
- structureId: structure.structureId,
38569
- matchUpsMap,
38570
- });
38571
- const result = getRoundContextProfile({
38572
- roundNamingPolicy,
38573
- drawDefinition,
38574
- structure,
38575
- matchUps,
38576
- });
38577
- const { roundNamingProfile, roundProfile } = result;
38578
- const structures = structure.structures || [structure];
38579
- structures.forEach((itemStructure) => {
38580
- (itemStructure.matchUps ?? []).forEach((matchUp) => {
38581
- const roundNumber = matchUp?.roundNumber?.toString();
38582
- if (roundNumber) {
38583
- const roundName = roundNamingProfile?.[roundNumber]?.roundName;
38584
- const abbreviatedRoundName = roundNamingProfile?.[roundNumber]?.abbreviatedRoundName;
38585
- const feedRound = roundProfile?.[roundNumber]?.feedRound;
38586
- Object.assign(matchUp, {
38587
- abbreviatedRoundName,
38588
- feedRound,
38589
- roundName,
38590
- });
38591
- }
38592
- });
38593
- });
38594
- });
38595
- }
38849
+ if (roundNamingPolicy)
38850
+ hydrateRoundNames({ drawDefinition, appliedPolicies });
38596
38851
  }
38597
38852
  return {
38598
38853
  existingDrawDefinition: !!existingDrawDefinition,
@@ -45982,8 +46237,7 @@ function progressExitStatus({ sourceMatchUpStatusCodes, propagateExitStatus, sou
45982
46237
  color: 'magenta',
45983
46238
  method: stack,
45984
46239
  });
45985
- const carryOverMatchUpStatus = (isExit(sourceMatchUpStatus) && (sourceMatchUpStatus !== RETIRED$1) && sourceMatchUpStatus)
45986
- || WALKOVER$2;
46240
+ const carryOverMatchUpStatus = (isExit(sourceMatchUpStatus) && sourceMatchUpStatus !== RETIRED$1 && sourceMatchUpStatus) || WALKOVER$2;
45987
46241
  const inContextMatchUps = getAllDrawMatchUps({
45988
46242
  inContext: true,
45989
46243
  drawDefinition,
@@ -46848,7 +47102,22 @@ function generateOutcomeFromScoreString(params) {
46848
47102
  };
46849
47103
  if (winningSide && ![1, 2, undefined].includes(winningSide))
46850
47104
  return { error: INVALID_VALUES, winningSide };
46851
- const neutralParsedSets = scoreString && parseScoreString({ scoreString });
47105
+ const neutralParsedSets = scoreString && parseScoreString({ scoreString, matchUpFormat });
47106
+ const isBracketNotation = scoreString?.trim().startsWith('[');
47107
+ let inferredWinningSide = winningSide;
47108
+ if (!inferredWinningSide && matchUpFormat && neutralParsedSets) {
47109
+ const setsWon = { side1: 0, side2: 0 };
47110
+ neutralParsedSets.forEach((set) => {
47111
+ if (set.winningSide === 1)
47112
+ setsWon.side1++;
47113
+ else if (set.winningSide === 2)
47114
+ setsWon.side2++;
47115
+ });
47116
+ if (setsWon.side1 > setsWon.side2)
47117
+ inferredWinningSide = 1;
47118
+ else if (setsWon.side2 > setsWon.side1)
47119
+ inferredWinningSide = 2;
47120
+ }
46852
47121
  const score = {};
46853
47122
  const winningScoreString = generateScoreString({
46854
47123
  sets: neutralParsedSets,
@@ -46861,7 +47130,11 @@ function generateOutcomeFromScoreString(params) {
46861
47130
  matchUpFormat,
46862
47131
  setTBlast,
46863
47132
  });
46864
- if (winningSide === 2) {
47133
+ if (isBracketNotation) {
47134
+ score.scoreStringSide1 = winningScoreString;
47135
+ score.scoreStringSide2 = losingScoreString;
47136
+ }
47137
+ else if (inferredWinningSide === 2) {
46865
47138
  score.scoreStringSide1 = losingScoreString;
46866
47139
  score.scoreStringSide2 = winningScoreString;
46867
47140
  }
@@ -46869,11 +47142,11 @@ function generateOutcomeFromScoreString(params) {
46869
47142
  score.scoreStringSide1 = winningScoreString;
46870
47143
  score.scoreStringSide2 = losingScoreString;
46871
47144
  }
46872
- score.sets = parseScoreString({ scoreString: score.scoreStringSide1 });
47145
+ score.sets = parseScoreString({ scoreString: score.scoreStringSide1, matchUpFormat });
46873
47146
  return definedAttributes({
46874
47147
  outcome: {
46875
47148
  matchUpStatus,
46876
- winningSide,
47149
+ winningSide: inferredWinningSide,
46877
47150
  score,
46878
47151
  },
46879
47152
  });
@@ -57258,6 +57531,24 @@ var generate$1 = {
57258
57531
  createTournamentRecord: createTournamentRecord
57259
57532
  };
57260
57533
 
57534
+ function hydrateTournamentRecord(params) {
57535
+ const { tournamentRecord, eventProfiles = [], directives, policyDefinitions } = params;
57536
+ if (!tournamentRecord)
57537
+ return { error: MISSING_TOURNAMENT_RECORD };
57538
+ const events = tournamentRecord.events || [];
57539
+ events.forEach((event) => {
57540
+ const eventProfile = eventProfiles.find((ep) => ep.eventId && ep.eventId === event.eventId);
57541
+ if (eventProfile?.directives?.hydrateRoundNames || directives?.hydrateRoundNames) {
57542
+ event.drawDefinitions?.forEach((drawDefinition) => {
57543
+ const roundNamingPolicy = eventProfile?.policyDefinitions?.[POLICY_TYPE_ROUND_NAMING] || policyDefinitions?.[POLICY_TYPE_ROUND_NAMING];
57544
+ if (roundNamingPolicy)
57545
+ hydrateRoundNames({ drawDefinition, appliedPolicies: policyDefinitions });
57546
+ });
57547
+ }
57548
+ });
57549
+ return { tournamentRecord };
57550
+ }
57551
+
57261
57552
  const ABANDONED = 'ABANDONED';
57262
57553
  const ACTIVE = 'ACTIVE';
57263
57554
  const CANCELLED = 'CANCELLED';
@@ -57649,6 +57940,7 @@ var mutate$1 = {
57649
57940
  addTimeItem: addTimeItem,
57650
57941
  addTournamentExtension: addTournamentExtension,
57651
57942
  addTournamentTimeItem: addTournamentTimeItem,
57943
+ hydrateTournamentRecord: hydrateTournamentRecord,
57652
57944
  removeDrawDefinitionExtension: removeDrawDefinitionExtension,
57653
57945
  removeEventExtension: removeEventExtension,
57654
57946
  removeExtension: removeExtension,
@@ -57696,6 +57988,7 @@ var index$3 = {
57696
57988
  getTournamentPoints: getTournamentPoints,
57697
57989
  getTournamentStructures: getTournamentStructures,
57698
57990
  getTournamentTimeItem: getTournamentTimeItem,
57991
+ hydrateTournamentRecord: hydrateTournamentRecord,
57699
57992
  mutate: mutate$1,
57700
57993
  query: query$7,
57701
57994
  removeDrawDefinitionExtension: removeDrawDefinitionExtension,