tods-competition-factory 1.7.2 → 1.7.4

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
@@ -333,7 +333,7 @@ const matchUpFormatCode = {
333
333
  };
334
334
 
335
335
  function factoryVersion() {
336
- return "1.7.2";
336
+ return "1.7.4";
337
337
  }
338
338
 
339
339
  function getObjectTieFormat(obj) {
@@ -4404,6 +4404,7 @@ function getMatchUpFormatAverageTimes({
4404
4404
  });
4405
4405
  }
4406
4406
 
4407
+ const DYNAMIC = "DYNAMIC";
4407
4408
  const RANKING$1 = "RANKING";
4408
4409
  const RATING$2 = "RATING";
4409
4410
  const SCALE$1 = "SCALE";
@@ -6183,7 +6184,7 @@ function getRoundMatchUps$1({
6183
6184
  roundProfile[roundNumber].finishingRound = finishingRoundMap[roundNumber]?.finishingRound;
6184
6185
  roundProfile[roundNumber].roundName = finishingRoundMap[roundNumber]?.roundName;
6185
6186
  roundProfile[roundNumber].abbreviatedRoundName = finishingRoundMap[roundNumber]?.abbreviatedRoundName;
6186
- roundProfile[roundNumber].finishingPositionRange = roundMatchUps[roundNumber][0].finishingPositionRange;
6187
+ roundProfile[roundNumber].finishingPositionRange = roundMatchUps[roundNumber]?.[0]?.finishingPositionRange;
6187
6188
  if (roundNumber === 1 || !roundProfile[roundNumber - 1]) {
6188
6189
  const orderedDrawPositions = currentRoundDrawPositions.sort(numericSort);
6189
6190
  const pairedDrawPositions = chunkArray(orderedDrawPositions, 2);
@@ -13381,21 +13382,27 @@ const ratingConstants = {
13381
13382
  const ratingsParameters = {
13382
13383
  [ELO]: { range: [0, 3e3], decimalsCount: 0, defaultInitialization: 1500 },
13383
13384
  [NTRP]: {
13384
- range: [1, 7],
13385
- decimalsCount: 1,
13386
- defaultInitialization: 3,
13387
- accessor: "dntrpRatingHundredths",
13388
13385
  accessors: ["ntrpRating", "dntrpRatingHundredths"],
13389
- attributes: { ustaRatingType: "" }
13386
+ attributes: { ustaRatingType: "" },
13387
+ accessor: "dntrpRatingHundredths",
13388
+ defaultInitialization: 3,
13389
+ decimalsCount: 1,
13390
+ range: [1, 7]
13390
13391
  },
13391
- [UTR]: { range: [1, 16], decimalsCount: 2, defaultInitialization: 6 },
13392
- [WTN]: {
13393
- range: [40, 1],
13392
+ [UTR]: {
13393
+ defaultInitialization: 6,
13394
+ accessors: ["utrRating"],
13395
+ accessor: "utrRating",
13394
13396
  decimalsCount: 2,
13397
+ range: [1, 16]
13398
+ },
13399
+ [WTN]: {
13400
+ attributes: { confidence: { generator: true, range: [60, 100] } },
13401
+ accessors: ["wtnRating", "confidence"],
13395
13402
  defaultInitialization: 23,
13396
13403
  accessor: "wtnRating",
13397
- accessors: ["wtnRating"],
13398
- attributes: { confidence: { generator: true, range: [60, 100] } }
13404
+ decimalsCount: 2,
13405
+ range: [40, 1]
13399
13406
  }
13400
13407
  };
13401
13408
 
@@ -28916,9 +28923,9 @@ function getParticipantEntries(params) {
28916
28923
  if (!participation)
28917
28924
  return;
28918
28925
  if (!finishingPositionRange)
28919
- finishingPositionRange = participation.finishingPositionRange;
28920
- if (diff(finishingPositionRange) > diff(participation.finishingPositionRange))
28921
- finishingPositionRange = participation.finishingPositionRange;
28926
+ finishingPositionRange = participation?.finishingPositionRange;
28927
+ if (diff(finishingPositionRange) > diff(participation?.finishingPositionRange))
28928
+ finishingPositionRange = participation?.finishingPositionRange;
28922
28929
  const notQualifying = participation.stage !== QUALIFYING;
28923
28930
  if (notQualifying)
28924
28931
  nonQualifyingOrder += 1;
@@ -28929,8 +28936,10 @@ function getParticipantEntries(params) {
28929
28936
  flightNumber
28930
28937
  });
28931
28938
  }).filter(Boolean);
28932
- participantAggregator.draws[drawId].finishingPositionRange = finishingPositionRange;
28933
- participantAggregator.draws[drawId].structureParticipation = orderedParticipation;
28939
+ if (participantAggregator.draws[drawId]) {
28940
+ participantAggregator.draws[drawId].finishingPositionRange = finishingPositionRange;
28941
+ participantAggregator.draws[drawId].structureParticipation = orderedParticipation;
28942
+ }
28934
28943
  }
28935
28944
  }
28936
28945
  }
@@ -39654,6 +39663,7 @@ function generateCurtisConsolation(params) {
39654
39663
  finishingPositionOffset,
39655
39664
  structureName = MAIN,
39656
39665
  stageSequence = 1,
39666
+ structureNameMap,
39657
39667
  staggeredEntry,
39658
39668
  stage = MAIN,
39659
39669
  matchUpType,
@@ -39687,8 +39697,9 @@ function generateCurtisConsolation(params) {
39687
39697
  const consolationItems = feedRoundOffsets.map((roundOffset, index) => {
39688
39698
  const stageSequence2 = index + 1;
39689
39699
  const { consolationStructure } = consolationFeedStructure({
39690
- structureId: uuids?.pop(),
39691
39700
  idPrefix: idPrefix && `${idPrefix}-c${index}`,
39701
+ structureId: uuids?.pop(),
39702
+ structureNameMap,
39692
39703
  stageSequence: stageSequence2,
39693
39704
  roundOffset,
39694
39705
  matchUpType,
@@ -39717,9 +39728,9 @@ function generateCurtisConsolation(params) {
39717
39728
  isMock
39718
39729
  });
39719
39730
  const playoffStructure = structureTemplate({
39731
+ structureName: structureNameMap?.[PLAY_OFF] || PLAY_OFF,
39720
39732
  structureId: uuids?.pop(),
39721
39733
  matchUps: playoffMatchUps,
39722
- structureName: PLAY_OFF,
39723
39734
  stageSequence: 2,
39724
39735
  stage: PLAY_OFF,
39725
39736
  matchUpType
@@ -39744,6 +39755,7 @@ function generateCurtisConsolation(params) {
39744
39755
  }
39745
39756
  function consolationFeedStructure({
39746
39757
  stageSequence = 1,
39758
+ structureNameMap,
39747
39759
  roundOffset = 0,
39748
39760
  matchUpType,
39749
39761
  structureId,
@@ -39764,7 +39776,8 @@ function consolationFeedStructure({
39764
39776
  isMock,
39765
39777
  uuids
39766
39778
  });
39767
- const structureName = `${CONSOLATION} ${index + 1}`;
39779
+ const defaultName = `${CONSOLATION} ${index + 1}`;
39780
+ const structureName = structureNameMap?.[defaultName] || defaultName;
39768
39781
  const consolationStructure = structureTemplate({
39769
39782
  matchUps: consolationMatchUps,
39770
39783
  stage: CONSOLATION,
@@ -40049,6 +40062,7 @@ function processPlayoffGroups({
40049
40062
  }
40050
40063
  const params = {
40051
40064
  structureId: playoffGroup.structureId ?? uuids?.pop(),
40065
+ structureNameMap: playoffGroup.structureNameMap,
40052
40066
  structureName: playoffGroup.structureName,
40053
40067
  idPrefix: idPrefix && `${idPrefix}-po`,
40054
40068
  appliedPolicies: policyDefinitions,
@@ -44332,21 +44346,30 @@ function generateAdHocMatchUps$1({
44332
44346
  structureId = drawDefinition.structures?.[0]?.structureId;
44333
44347
  if (typeof structureId !== "string")
44334
44348
  return { error: MISSING_STRUCTURE_ID };
44335
- if (newRound && !matchUpsCount) {
44349
+ const structure = drawDefinition.structures?.find(
44350
+ (structure2) => structure2.structureId === structureId
44351
+ );
44352
+ if (!structure)
44353
+ return { error: STRUCTURE_NOT_FOUND };
44354
+ if (!matchUpsCount) {
44336
44355
  const selectedEntries = drawDefinition?.entries?.filter((entry) => {
44337
44356
  const entryStatus = entry.entryStatus;
44338
44357
  return STRUCTURE_SELECTED_STATUSES.includes(entryStatus);
44339
44358
  }) ?? [];
44340
- matchUpsCount = Math.floor(selectedEntries?.length / 2) || 1;
44359
+ const roundMatchUpsCount = Math.floor(selectedEntries?.length / 2) || 1;
44360
+ if (newRound) {
44361
+ matchUpsCount = roundMatchUpsCount;
44362
+ } else {
44363
+ const maxRemaining = roundMatchUpsCount - (structure.matchUps?.length || 0);
44364
+ if (maxRemaining > 0)
44365
+ matchUpsCount = maxRemaining;
44366
+ }
44341
44367
  }
44342
44368
  if (participantIdPairings && !Array.isArray(participantIdPairings) || matchUpsCount && !isConvertableInteger(matchUpsCount) || matchUpIds && !Array.isArray(matchUpIds) || !participantIdPairings && !matchUpsCount) {
44343
44369
  return { error: INVALID_VALUES, info: "matchUpsCount or pairings error" };
44344
44370
  }
44345
- const structure = drawDefinition?.structures?.find(
44346
- (structure2) => structure2.structureId === structureId
44347
- );
44348
44371
  let structureHasRoundPositions;
44349
- const existingMatchUps = structure?.matchUps;
44372
+ const existingMatchUps = structure.matchUps ?? [];
44350
44373
  const lastRoundNumber = existingMatchUps?.reduce(
44351
44374
  (roundNumber2, matchUp) => {
44352
44375
  if (matchUp.roundPosition)
@@ -44355,12 +44378,12 @@ function generateAdHocMatchUps$1({
44355
44378
  },
44356
44379
  0
44357
44380
  );
44358
- if (structure?.structures || structureHasRoundPositions || structure?.finishingPosition === ROUND_OUTCOME) {
44381
+ if (structure.structures || structureHasRoundPositions || structure.finishingPosition === ROUND_OUTCOME) {
44359
44382
  return { error: INVALID_STRUCTURE };
44360
44383
  }
44361
44384
  if (roundNumber && roundNumber - 1 > (lastRoundNumber || 0))
44362
44385
  return { error: INVALID_VALUES, info: "roundNumber error" };
44363
- const nextRoundNumber = roundNumber ?? (newRound ? (lastRoundNumber ?? 0) + 1 : lastRoundNumber ?? 1);
44386
+ const nextRoundNumber = roundNumber ?? (newRound && (lastRoundNumber ?? 0) + 1 || lastRoundNumber || 1);
44364
44387
  participantIdPairings = participantIdPairings ?? generateRange(0, matchUpsCount).map(() => ({
44365
44388
  participantIds: [void 0, void 0]
44366
44389
  }));
@@ -46701,60 +46724,93 @@ function removeDelegatedOutcome$1({ drawDefinition, event, matchUpId }) {
46701
46724
  }
46702
46725
 
46703
46726
  function generateCandidate({
46704
- maxIterations = 5e3,
46727
+ maxIterations = 4e3,
46705
46728
  // cap the processing intensity of the candidate generator
46706
46729
  valueSortedPairings,
46707
46730
  // pairings sorted by value from low to high
46708
46731
  pairingValues,
46732
+ valueObjects,
46709
46733
  deltaObjects
46710
46734
  }) {
46711
- const rankedMatchUpValues = Object.assign(
46735
+ const pairingValueMap = Object.assign(
46712
46736
  {},
46713
46737
  ...valueSortedPairings.map((rm) => ({ [rm.pairing]: rm.value }))
46714
46738
  );
46715
- let candidate = roundCandidate({
46716
- rankedMatchUpValues,
46739
+ const actors = Object.keys(pairingValues);
46740
+ let proposedCandidates = [];
46741
+ const initialProposal = roundCandidate({
46742
+ actorsCount: actors.length,
46717
46743
  valueSortedPairings,
46718
- deltaObjects
46744
+ pairingValueMap,
46745
+ deltaObjects,
46746
+ valueObjects
46719
46747
  });
46720
- let deltaCandidate = candidate;
46721
- const actors = Object.keys(pairingValues);
46748
+ const candidateHashes = [candidateHash(initialProposal)];
46749
+ proposedCandidates.push(initialProposal);
46750
+ let lowCandidateValue = initialProposal.value;
46751
+ let deltaCandidate = initialProposal;
46722
46752
  let candidatesCount = 0;
46723
- let iterations;
46753
+ let iterations = 0;
46724
46754
  let opponentCount = actors.length;
46755
+ let calculatedIterations;
46725
46756
  do {
46726
46757
  opponentCount -= 1;
46727
- iterations = actors.length * opponentCount * valueSortedPairings.length / 2;
46728
- } while (iterations > maxIterations && opponentCount > 2);
46758
+ calculatedIterations = actors.length * pairingValues[actors[0]].length;
46759
+ } while (calculatedIterations > maxIterations && opponentCount > 5);
46729
46760
  const stipulatedPairs = [];
46730
46761
  actors.forEach((actor) => {
46731
46762
  const participantIdPairings = pairingValues[actor];
46732
46763
  participantIdPairings.slice(0, opponentCount).forEach((pairing) => {
46764
+ iterations += 1;
46733
46765
  const stipulatedPair = pairingHash(actor, pairing.opponent);
46734
46766
  if (!stipulatedPairs.includes(stipulatedPair)) {
46735
46767
  const proposed = roundCandidate({
46736
46768
  // each roundCandidate starts with stipulated pairings
46737
46769
  stipulated: [[actor, pairing.opponent]],
46738
- rankedMatchUpValues,
46770
+ actorsCount: actors.length,
46739
46771
  valueSortedPairings,
46740
- deltaObjects
46772
+ pairingValueMap,
46773
+ deltaObjects,
46774
+ valueObjects
46741
46775
  });
46742
- if (proposed.maxDelta < deltaCandidate.maxDelta)
46743
- deltaCandidate = proposed;
46744
- if (proposed.value < candidate.value)
46745
- candidate = proposed;
46746
- stipulatedPairs.push(stipulatedPair);
46747
- candidatesCount += 1;
46776
+ if (!candidateHashes.includes(candidateHash(proposed))) {
46777
+ candidateHashes.push(candidateHash(proposed));
46778
+ proposedCandidates.push(proposed);
46779
+ const { maxDelta, value } = proposed;
46780
+ if (maxDelta < deltaCandidate.maxDelta)
46781
+ deltaCandidate = proposed;
46782
+ if (value < lowCandidateValue || value === lowCandidateValue && Math.round(Math.random())) {
46783
+ lowCandidateValue = value;
46784
+ }
46785
+ stipulatedPairs.push(stipulatedPair);
46786
+ candidatesCount += 1;
46787
+ }
46748
46788
  }
46749
46789
  });
46790
+ proposedCandidates = proposedCandidates.filter(
46791
+ (proposed) => Math.abs(proposed.value - lowCandidateValue) < 5
46792
+ );
46750
46793
  });
46751
- return { candidate, deltaCandidate, candidatesCount, iterations };
46794
+ proposedCandidates.sort((a, b) => a.maxDiff - b.maxDiff);
46795
+ const candidate = randomPop(proposedCandidates);
46796
+ return {
46797
+ candidatesCount,
46798
+ deltaCandidate,
46799
+ maxIterations,
46800
+ iterations,
46801
+ candidate
46802
+ };
46803
+ }
46804
+ function candidateHash(candidate) {
46805
+ return candidate.participantIdPairings.map(({ participantIds }) => participantIds.sort().join("|")).sort().join("/");
46752
46806
  }
46753
46807
  function roundCandidate({
46754
- rankedMatchUpValues,
46755
46808
  valueSortedPairings,
46756
46809
  stipulated = [],
46757
- deltaObjects
46810
+ pairingValueMap,
46811
+ deltaObjects,
46812
+ valueObjects,
46813
+ actorsCount
46758
46814
  }) {
46759
46815
  const roundPlayers = [].concat(...stipulated);
46760
46816
  const participantIdPairings = [];
@@ -46762,11 +46818,17 @@ function roundCandidate({
46762
46818
  stipulated.filter(Boolean).forEach((participantIds) => {
46763
46819
  const [p1, p2] = participantIds;
46764
46820
  const pairing = pairingHash(p1, p2);
46765
- const value = rankedMatchUpValues[pairing];
46821
+ const value = pairingValueMap[pairing];
46766
46822
  participantIdPairings.push({ participantIds, value });
46767
- candidateValue += rankedMatchUpValues[pairing];
46823
+ candidateValue += pairingValueMap[pairing];
46768
46824
  });
46769
- valueSortedPairings.forEach((rankedPairing) => {
46825
+ const consideredPairings = chunkArray(valueSortedPairings, actorsCount).map(
46826
+ (pairings) => shuffleArray(pairings).map((pairing) => ({
46827
+ ...pairing,
46828
+ value: pairing.value + Math.random() * Math.round(Math.random())
46829
+ }))
46830
+ ).flat();
46831
+ consideredPairings.forEach((rankedPairing) => {
46770
46832
  const participantIds = rankedPairing.pairing.split("|");
46771
46833
  const opponentExists = participantIds.reduce(
46772
46834
  (p, c) => roundPlayers.includes(c) || p,
@@ -46786,15 +46848,154 @@ function roundCandidate({
46786
46848
  const delta = deltaObjects[hash];
46787
46849
  return delta > p ? delta : p;
46788
46850
  }, 0);
46789
- return { value: candidateValue, participantIdPairings, maxDelta };
46851
+ const maxDiff = participantIdPairings.reduce((p, c) => {
46852
+ const [p1, p2] = c.participantIds;
46853
+ const hash = pairingHash(p1, p2);
46854
+ const diff = valueObjects[hash];
46855
+ return diff > p ? diff : p;
46856
+ }, 0);
46857
+ return { value: candidateValue, participantIdPairings, maxDelta, maxDiff };
46790
46858
  }
46791
46859
  function pairingHash(id1, id2) {
46792
46860
  return [id1, id2].sort().join("|");
46793
46861
  }
46794
46862
 
46795
- const ENCOUNTER_VALUE = 50;
46796
- const SAME_TEAM_VALUE = 60;
46863
+ function getPairingsData({ participantIds }) {
46864
+ const possiblePairings = {};
46865
+ const uniquePairings = [];
46866
+ participantIds.forEach((participantId) => {
46867
+ possiblePairings[participantId] = participantIds.filter(
46868
+ (id) => id !== participantId
46869
+ );
46870
+ possiblePairings[participantId].forEach((id) => {
46871
+ const pairing = pairingHash(id, participantId);
46872
+ if (!uniquePairings.includes(pairing))
46873
+ uniquePairings.push(pairing);
46874
+ });
46875
+ });
46876
+ const deltaObjects = Object.assign(
46877
+ {},
46878
+ ...uniquePairings.map((pairing) => ({ [pairing]: 0 }))
46879
+ );
46880
+ return { uniquePairings, possiblePairings, deltaObjects };
46881
+ }
46882
+
46883
+ function getEncounters({ matchUps }) {
46884
+ const encounters = [];
46885
+ for (const matchUp of matchUps) {
46886
+ const participantIds = matchUp.sides.map(
46887
+ extractAttributes("participantId")
46888
+ );
46889
+ if (participantIds.length === 2) {
46890
+ const [p1, p2] = participantIds;
46891
+ const pairing = pairingHash(p1, p2);
46892
+ if (!encounters.includes(pairing))
46893
+ encounters.push(pairing);
46894
+ }
46895
+ }
46896
+ return { encounters };
46897
+ }
46898
+
46899
+ function getParticipantPairingValues({
46900
+ possiblePairings,
46901
+ valueObjects
46902
+ }) {
46903
+ const pairingValues = {};
46904
+ for (const participantId of Object.keys(possiblePairings)) {
46905
+ const participantValues = possiblePairings[participantId].map(
46906
+ (opponent) => pairingValue(participantId, opponent)
46907
+ );
46908
+ pairingValues[participantId] = participantValues.sort(
46909
+ (a, b) => a.value - b.value
46910
+ );
46911
+ }
46912
+ function pairingValue(participantId, opponent) {
46913
+ const key = pairingHash(participantId, opponent);
46914
+ return { opponent, value: valueObjects[key] };
46915
+ }
46916
+ return { pairingValues };
46917
+ }
46918
+
46797
46919
  const DEFAULT_RATING = 0;
46920
+ function getSideRatings({
46921
+ tournamentParticipants,
46922
+ adHocRatings,
46923
+ eventType,
46924
+ scaleName,
46925
+ pairing
46926
+ }) {
46927
+ const defaultRating = ratingsParameters[scaleName]?.defaultInitialization ?? DEFAULT_RATING;
46928
+ return pairing.split("|").map((participantId) => {
46929
+ if (eventType === DOUBLES) {
46930
+ const individualParticipantIds = tournamentParticipants?.find(
46931
+ (participant) => participant.participantId === participantId
46932
+ )?.individualParticipantIds;
46933
+ return !individualParticipantIds ? defaultRating * 2 : individualParticipantIds?.map(
46934
+ (participantId2) => adHocRatings[participantId2] || defaultRating
46935
+ );
46936
+ } else {
46937
+ return adHocRatings[participantId] || defaultRating;
46938
+ }
46939
+ });
46940
+ }
46941
+
46942
+ function getPairings({
46943
+ tournamentParticipants,
46944
+ adHocRatings = {},
46945
+ possiblePairings,
46946
+ // participant keyed; provides array of possible opponents
46947
+ uniquePairings,
46948
+ // hashes of all possible participantId pairings
46949
+ maxIterations,
46950
+ deltaObjects,
46951
+ // difference in rating between paired participants
46952
+ valueObjects,
46953
+ // calculated value of a pairing of participants, used for sorting pairings
46954
+ eventType,
46955
+ scaleName,
46956
+ salted
46957
+ }) {
46958
+ uniquePairings.forEach((pairing) => {
46959
+ const ratings = getSideRatings({
46960
+ tournamentParticipants,
46961
+ adHocRatings,
46962
+ scaleName,
46963
+ eventType,
46964
+ pairing
46965
+ });
46966
+ const salting = typeof salted === "number" && salted || 0.5;
46967
+ const salt = salted && (Math.round(Math.random()) ? salting : salting * -1) || 0;
46968
+ const ratingsDifference = Math.abs(ratings[0] - ratings[1]) + salt;
46969
+ const pairingDelta = Math.abs(ratings[0] - ratings[1]);
46970
+ deltaObjects[pairing] = pairingDelta;
46971
+ if (!valueObjects[pairing])
46972
+ valueObjects[pairing] = 0;
46973
+ valueObjects[pairing] += ratingsDifference ? Math.pow(ratingsDifference, 2) : 0;
46974
+ });
46975
+ const valueSortedPairings = uniquePairings.map((pairing) => ({ pairing, value: valueObjects[pairing] })).sort((a, b) => a.value - b.value);
46976
+ const { pairingValues } = getParticipantPairingValues({
46977
+ possiblePairings,
46978
+ valueObjects
46979
+ });
46980
+ const { candidate, candidatesCount, deltaCandidate, iterations } = generateCandidate({
46981
+ valueSortedPairings,
46982
+ maxIterations,
46983
+ pairingValues,
46984
+ deltaObjects,
46985
+ valueObjects
46986
+ });
46987
+ const { participantIdPairings } = candidate;
46988
+ return {
46989
+ participantIdPairings,
46990
+ candidatesCount,
46991
+ deltaCandidate,
46992
+ iterations,
46993
+ candidate
46994
+ };
46995
+ }
46996
+
46997
+ const ENCOUNTER_VALUE = 100;
46998
+ const SAME_TEAM_VALUE = 100;
46798
46999
  const MAX_ITERATIONS = 5e3;
46799
47000
  function generateDrawMaticRound({
46800
47001
  maxIterations = MAX_ITERATIONS,
@@ -46806,9 +47007,11 @@ function generateDrawMaticRound({
46806
47007
  drawDefinition,
46807
47008
  adHocRatings,
46808
47009
  structureId,
47010
+ salted = 0.5,
46809
47011
  matchUpIds,
46810
47012
  eventType,
46811
- structure
47013
+ structure,
47014
+ scaleName
46812
47015
  }) {
46813
47016
  if (!drawDefinition)
46814
47017
  return { error: MISSING_DRAW_DEFINITION };
@@ -46857,7 +47060,9 @@ function generateDrawMaticRound({
46857
47060
  deltaObjects,
46858
47061
  valueObjects,
46859
47062
  eventType,
46860
- structure
47063
+ scaleName,
47064
+ structure,
47065
+ salted
46861
47066
  };
46862
47067
  const { candidatesCount, participantIdPairings, iterations } = getPairings(params);
46863
47068
  if (!candidatesCount)
@@ -46885,118 +47090,11 @@ function generateDrawMaticRound({
46885
47090
  matchUps
46886
47091
  };
46887
47092
  }
46888
- function getSideRatings({
46889
- tournamentParticipants,
46890
- adHocRatings,
46891
- eventType,
46892
- pairing
46893
- }) {
46894
- return pairing.split("|").map((participantId) => {
46895
- if (eventType === DOUBLES) {
46896
- const individualParticipantIds = tournamentParticipants?.find(
46897
- (participant) => participant.participantId === participantId
46898
- )?.individualParticipantIds;
46899
- return !individualParticipantIds ? DEFAULT_RATING * 2 : individualParticipantIds?.map(
46900
- (participantId2) => adHocRatings[participantId2 || DEFAULT_RATING]
46901
- );
46902
- } else {
46903
- return adHocRatings[participantId] || DEFAULT_RATING;
46904
- }
46905
- });
46906
- }
46907
- function getPairings({
46908
- tournamentParticipants,
46909
- adHocRatings = {},
46910
- possiblePairings,
46911
- // participant keyed; provides array of possible opponents
46912
- uniquePairings,
46913
- // hashes of all possible participantId pairings
46914
- maxIterations,
46915
- deltaObjects,
46916
- // difference in rating between paired participants
46917
- valueObjects,
46918
- // calculated value of a pairing of participants, used for sorting pairings
46919
- eventType
46920
- }) {
46921
- uniquePairings.forEach((pairing) => {
46922
- const ratings = getSideRatings({
46923
- tournamentParticipants,
46924
- adHocRatings,
46925
- eventType,
46926
- pairing
46927
- });
46928
- const ratingsDifference = Math.abs(ratings[0] - ratings[1]) + 1;
46929
- deltaObjects[pairing] = Math.abs(ratings[0] - ratings[1]);
46930
- if (!valueObjects[pairing])
46931
- valueObjects[pairing] = 0;
46932
- valueObjects[pairing] += Math.pow(ratingsDifference, 2);
46933
- });
46934
- const valueSortedPairings = uniquePairings.map((pairing) => ({ pairing, value: valueObjects[pairing] })).sort((a, b) => a.value - b.value);
46935
- const { pairingValues } = getParticipantPairingValues({
46936
- possiblePairings,
46937
- valueObjects
46938
- });
46939
- const { candidate, candidatesCount, iterations } = generateCandidate({
46940
- valueSortedPairings,
46941
- maxIterations,
46942
- pairingValues,
46943
- deltaObjects
46944
- });
46945
- const { participantIdPairings } = candidate;
46946
- return { candidatesCount, participantIdPairings, iterations };
46947
- }
46948
- function getPairingsData({ participantIds }) {
46949
- const possiblePairings = {};
46950
- const uniquePairings = [];
46951
- participantIds.forEach((participantId) => {
46952
- possiblePairings[participantId] = participantIds.filter(
46953
- (id) => id !== participantId
46954
- );
46955
- possiblePairings[participantId].forEach((id) => {
46956
- const pairing = pairingHash(id, participantId);
46957
- if (!uniquePairings.includes(pairing))
46958
- uniquePairings.push(pairing);
46959
- });
46960
- });
46961
- const deltaObjects = Object.assign(
46962
- {},
46963
- ...uniquePairings.map((pairing) => ({ [pairing]: 0 }))
46964
- );
46965
- return { uniquePairings, possiblePairings, deltaObjects };
46966
- }
46967
- function getEncounters({ matchUps }) {
46968
- const encounters = [];
46969
- for (const matchUp of matchUps) {
46970
- const participantIds = matchUp.sides.map(getParticipantId);
46971
- if (participantIds.length === 2) {
46972
- const [p1, p2] = participantIds;
46973
- const pairing = pairingHash(p1, p2);
46974
- if (!encounters.includes(pairing))
46975
- encounters.push(pairing);
46976
- }
46977
- }
46978
- return { encounters };
46979
- }
46980
- function getParticipantPairingValues({ possiblePairings, valueObjects }) {
46981
- const pairingValues = {};
46982
- for (const participantId of Object.keys(possiblePairings)) {
46983
- const participantValues = possiblePairings[participantId].map(
46984
- (opponent) => pairingValue(participantId, opponent)
46985
- );
46986
- pairingValues[participantId] = participantValues.sort(
46987
- (a, b) => a.value - b.value
46988
- );
46989
- }
46990
- function pairingValue(participantId, opponent) {
46991
- const key = pairingHash(participantId, opponent);
46992
- return { opponent, value: valueObjects[key] };
46993
- }
46994
- return { pairingValues };
46995
- }
46996
47093
 
46997
47094
  function drawMatic$1({
46998
47095
  tournamentParticipants,
46999
47096
  restrictEntryStatus,
47097
+ adHocRatings = {},
47000
47098
  tournamentRecord,
47001
47099
  generateMatchUps,
47002
47100
  addToStructure,
@@ -47051,12 +47149,16 @@ function drawMatic$1({
47051
47149
  if (!structureIsAdHoc)
47052
47150
  return { error: INVALID_DRAW_DEFINITION };
47053
47151
  tournamentParticipants = tournamentParticipants ?? tournamentRecord.participants ?? [];
47054
- const adHocRatings = {};
47055
47152
  for (const participantId of participantIds ?? []) {
47056
47153
  const participant = tournamentParticipants?.find(
47057
47154
  (participant2) => participant2.participantId === participantId
47058
47155
  );
47059
- let scaleValue = getScaleValue({ eventType, participant });
47156
+ let scaleValue = getScaleValue({
47157
+ scaleName: `${scaleName}.${DYNAMIC}`,
47158
+ scaleAccessor,
47159
+ participant,
47160
+ eventType
47161
+ });
47060
47162
  if (!scaleValue && scaleName) {
47061
47163
  scaleValue = getScaleValue({
47062
47164
  scaleAccessor,
@@ -47065,7 +47167,7 @@ function drawMatic$1({
47065
47167
  eventType
47066
47168
  });
47067
47169
  }
47068
- if (scaleValue)
47170
+ if (scaleValue && !adHocRatings[participantId])
47069
47171
  adHocRatings[participantId] = scaleValue;
47070
47172
  }
47071
47173
  return generateDrawMaticRound({
@@ -47083,14 +47185,15 @@ function drawMatic$1({
47083
47185
  });
47084
47186
  }
47085
47187
  function getScaleValue({
47086
- eventType = TypeEnum.Singles,
47087
- scaleName = "dynamic",
47188
+ scaleType = RATING$2,
47088
47189
  scaleAccessor,
47089
- participant
47190
+ participant,
47191
+ scaleName,
47192
+ eventType
47090
47193
  }) {
47091
47194
  const scaleAttributes = {
47092
47195
  eventType: eventType || TypeEnum.Singles,
47093
- scaleType: RATING$2,
47196
+ scaleType,
47094
47197
  scaleName
47095
47198
  };
47096
47199
  const result = participant && participantScaleItem({
@@ -59464,11 +59567,15 @@ function calculateNewRatings(params) {
59464
59567
  targetRange: consideredRange
59465
59568
  });
59466
59569
  const updatedWinnerRating = invertedScale ? ratingRange[0] - convertedUpdatedWinnerRating : convertedUpdatedWinnerRating;
59467
- let newWinnerRating = parseFloat(updatedWinnerRating).toFixed(decimalPlaces);
59570
+ let newWinnerRating = parseFloat(
59571
+ parseFloat(updatedWinnerRating).toFixed(decimalPlaces)
59572
+ );
59468
59573
  const updatedLoserRating = invertedScale ? ratingRange[0] - convertedUpdatedLoserRating : convertedUpdatedLoserRating;
59469
- let newLoserRating = parseFloat(updatedLoserRating).toFixed(decimalPlaces);
59574
+ let newLoserRating = parseFloat(
59575
+ parseFloat(updatedLoserRating).toFixed(decimalPlaces)
59576
+ );
59470
59577
  const percentageDifference = Math.max(...ratingRange) ? Math.abs(winnerRating - loserRating) / Math.max(...ratingRange) : 0;
59471
- if (convertedUpdatedWinnerRating > convertedUpdatedLoserRating && percentageDifference > eloConfig.diffThreshold || parseFloat(newWinnerRating) < 0 || parseFloat(newLoserRating) < 0) {
59578
+ if (convertedUpdatedWinnerRating > convertedUpdatedLoserRating && percentageDifference > eloConfig.diffThreshold || newWinnerRating < 0 || newLoserRating < 0) {
59472
59579
  newWinnerRating = winnerRating;
59473
59580
  newLoserRating = loserRating;
59474
59581
  }
@@ -59486,7 +59593,8 @@ const aggregateSets = (sets) => {
59486
59593
  ) || [0, 0];
59487
59594
  };
59488
59595
 
59489
- function processMatchUps({
59596
+ function generateDynamicRatings({
59597
+ removePriorValues = true,
59490
59598
  tournamentRecord,
59491
59599
  ratingType = ELO,
59492
59600
  considerGames,
@@ -59517,7 +59625,7 @@ function processMatchUps({
59517
59625
  scaleName: ratingType,
59518
59626
  scaleType: RATING$2
59519
59627
  };
59520
- const dynamicScaleName = `${ratingType}.DYNAMIC`;
59628
+ const dynamicScaleName = `${ratingType}.${DYNAMIC}`;
59521
59629
  const dynamicScaleAttributes = {
59522
59630
  scaleName: dynamicScaleName,
59523
59631
  eventType: matchUpType,
@@ -59553,9 +59661,9 @@ function processMatchUps({
59553
59661
  return participantId && {
59554
59662
  [participantId]: dynamicScaleItem ?? scaleItem ?? {
59555
59663
  scaleName: outputScaleName,
59556
- scaleType: RATING$2,
59557
59664
  eventType: matchUpType,
59558
59665
  scaleDate: endDate,
59666
+ scaleType: RATING$2,
59559
59667
  scaleValue
59560
59668
  }
59561
59669
  };
@@ -59584,27 +59692,35 @@ function processMatchUps({
59584
59692
  loserRating,
59585
59693
  ratingType
59586
59694
  });
59587
- const newWinnerScaleValue = accessor ? { ...winnerScaleValue, [accessor]: newWinnerRating } : newWinnerRating;
59588
- const newLoserScaleValue = accessor ? { ...loserScaleValue, [accessor]: newLoserRating } : newLoserRating;
59695
+ const newWinnerScaleValue = accessor ? {
59696
+ ...winnerScaleValue,
59697
+ [accessor]: newWinnerRating
59698
+ } : newWinnerRating;
59699
+ const newLoserScaleValue = accessor ? {
59700
+ ...loserScaleValue,
59701
+ [accessor]: newLoserRating
59702
+ } : newLoserRating;
59589
59703
  scaleItemMap[winnerParticipantId].scaleValue = newWinnerScaleValue;
59590
59704
  scaleItemMap[loserParticipantId].scaleValue = newLoserScaleValue;
59591
59705
  let result = setParticipantScaleItem({
59706
+ participantId: winnerParticipantId,
59707
+ removePriorValues,
59708
+ tournamentRecord,
59592
59709
  scaleItem: {
59593
59710
  ...scaleItemMap[winnerParticipantId],
59594
59711
  scaleName: outputScaleName
59595
- },
59596
- participantId: winnerParticipantId,
59597
- tournamentRecord
59712
+ }
59598
59713
  });
59599
59714
  if (result.error)
59600
59715
  return result;
59601
59716
  result = setParticipantScaleItem({
59717
+ participantId: loserParticipantId,
59718
+ removePriorValues,
59719
+ tournamentRecord,
59602
59720
  scaleItem: {
59603
59721
  ...scaleItemMap[loserParticipantId],
59604
59722
  scaleName: outputScaleName
59605
- },
59606
- participantId: loserParticipantId,
59607
- tournamentRecord
59723
+ }
59608
59724
  });
59609
59725
  if (result.error)
59610
59726
  return result;
@@ -59618,7 +59734,7 @@ function processMatchUps({
59618
59734
 
59619
59735
  const governor = {
59620
59736
  calculateNewRatings,
59621
- processMatchUps
59737
+ generateDynamicRatings
59622
59738
  };
59623
59739
 
59624
59740
  const scaleEngine = (() => {