tods-competition-factory 1.7.3 → 1.7.5

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.3";
336
+ return "1.7.5";
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";
@@ -4428,14 +4429,15 @@ function getScaleValues({ participant }) {
4428
4429
  for (const itemType of itemTypes) {
4429
4430
  const scaleItem = latestScaleItem(itemType);
4430
4431
  if (scaleItem) {
4431
- const [, type, format, scaleName] = scaleItem.itemType.split(".");
4432
+ const [, type, format, scaleName, modifier] = scaleItem.itemType.split(".");
4433
+ const namedScale = modifier ? `${scaleName}.${modifier}` : scaleName;
4432
4434
  const scaleType = type === SEEDING$1 && "seedings" || type === RANKING$1 && "rankings" || "ratings";
4433
4435
  if (!scales[scaleType][format])
4434
4436
  scales[scaleType][format] = [];
4435
4437
  scales[scaleType][format].push({
4436
4438
  scaleValue: scaleItem.itemValue,
4437
4439
  scaleDate: scaleItem.itemDate,
4438
- scaleName
4440
+ scaleName: namedScale
4439
4441
  });
4440
4442
  }
4441
4443
  }
@@ -13381,21 +13383,27 @@ const ratingConstants = {
13381
13383
  const ratingsParameters = {
13382
13384
  [ELO]: { range: [0, 3e3], decimalsCount: 0, defaultInitialization: 1500 },
13383
13385
  [NTRP]: {
13384
- range: [1, 7],
13385
- decimalsCount: 1,
13386
- defaultInitialization: 3,
13387
- accessor: "dntrpRatingHundredths",
13388
13386
  accessors: ["ntrpRating", "dntrpRatingHundredths"],
13389
- attributes: { ustaRatingType: "" }
13387
+ attributes: { ustaRatingType: "" },
13388
+ accessor: "dntrpRatingHundredths",
13389
+ defaultInitialization: 3,
13390
+ decimalsCount: 1,
13391
+ range: [1, 7]
13390
13392
  },
13391
- [UTR]: { range: [1, 16], decimalsCount: 2, defaultInitialization: 6 },
13392
- [WTN]: {
13393
- range: [40, 1],
13393
+ [UTR]: {
13394
+ defaultInitialization: 6,
13395
+ accessors: ["utrRating"],
13396
+ accessor: "utrRating",
13394
13397
  decimalsCount: 2,
13398
+ range: [1, 16]
13399
+ },
13400
+ [WTN]: {
13401
+ attributes: { confidence: { generator: true, range: [60, 100] } },
13402
+ accessors: ["wtnRating", "confidence"],
13395
13403
  defaultInitialization: 23,
13396
13404
  accessor: "wtnRating",
13397
- accessors: ["wtnRating"],
13398
- attributes: { confidence: { generator: true, range: [60, 100] } }
13405
+ decimalsCount: 2,
13406
+ range: [40, 1]
13399
13407
  }
13400
13408
  };
13401
13409
 
@@ -38815,7 +38823,7 @@ function treeMatchUps({
38815
38823
  uuids
38816
38824
  }));
38817
38825
  roundNumber++;
38818
- roundLimit = roundLimit || qualifyingRoundNumber || (qualifyingPositions ? drawSize / 2 / qualifyingPositions : void 0);
38826
+ roundLimit = roundLimit || qualifyingRoundNumber;
38819
38827
  while (roundNodes.length > 1) {
38820
38828
  if (qualifyingPositions && roundNodes.length === qualifyingPositions) {
38821
38829
  roundLimit = roundNumber - 1;
@@ -39656,6 +39664,7 @@ function generateCurtisConsolation(params) {
39656
39664
  finishingPositionOffset,
39657
39665
  structureName = MAIN,
39658
39666
  stageSequence = 1,
39667
+ structureNameMap,
39659
39668
  staggeredEntry,
39660
39669
  stage = MAIN,
39661
39670
  matchUpType,
@@ -39689,8 +39698,9 @@ function generateCurtisConsolation(params) {
39689
39698
  const consolationItems = feedRoundOffsets.map((roundOffset, index) => {
39690
39699
  const stageSequence2 = index + 1;
39691
39700
  const { consolationStructure } = consolationFeedStructure({
39692
- structureId: uuids?.pop(),
39693
39701
  idPrefix: idPrefix && `${idPrefix}-c${index}`,
39702
+ structureId: uuids?.pop(),
39703
+ structureNameMap,
39694
39704
  stageSequence: stageSequence2,
39695
39705
  roundOffset,
39696
39706
  matchUpType,
@@ -39719,9 +39729,9 @@ function generateCurtisConsolation(params) {
39719
39729
  isMock
39720
39730
  });
39721
39731
  const playoffStructure = structureTemplate({
39732
+ structureName: structureNameMap?.[PLAY_OFF] || PLAY_OFF,
39722
39733
  structureId: uuids?.pop(),
39723
39734
  matchUps: playoffMatchUps,
39724
- structureName: PLAY_OFF,
39725
39735
  stageSequence: 2,
39726
39736
  stage: PLAY_OFF,
39727
39737
  matchUpType
@@ -39746,6 +39756,7 @@ function generateCurtisConsolation(params) {
39746
39756
  }
39747
39757
  function consolationFeedStructure({
39748
39758
  stageSequence = 1,
39759
+ structureNameMap,
39749
39760
  roundOffset = 0,
39750
39761
  matchUpType,
39751
39762
  structureId,
@@ -39766,7 +39777,8 @@ function consolationFeedStructure({
39766
39777
  isMock,
39767
39778
  uuids
39768
39779
  });
39769
- const structureName = `${CONSOLATION} ${index + 1}`;
39780
+ const defaultName = `${CONSOLATION} ${index + 1}`;
39781
+ const structureName = structureNameMap?.[defaultName] || defaultName;
39770
39782
  const consolationStructure = structureTemplate({
39771
39783
  matchUps: consolationMatchUps,
39772
39784
  stage: CONSOLATION,
@@ -40051,6 +40063,7 @@ function processPlayoffGroups({
40051
40063
  }
40052
40064
  const params = {
40053
40065
  structureId: playoffGroup.structureId ?? uuids?.pop(),
40066
+ structureNameMap: playoffGroup.structureNameMap,
40054
40067
  structureName: playoffGroup.structureName,
40055
40068
  idPrefix: idPrefix && `${idPrefix}-po`,
40056
40069
  appliedPolicies: policyDefinitions,
@@ -46712,60 +46725,93 @@ function removeDelegatedOutcome$1({ drawDefinition, event, matchUpId }) {
46712
46725
  }
46713
46726
 
46714
46727
  function generateCandidate({
46715
- maxIterations = 5e3,
46728
+ maxIterations = 4e3,
46716
46729
  // cap the processing intensity of the candidate generator
46717
46730
  valueSortedPairings,
46718
46731
  // pairings sorted by value from low to high
46719
46732
  pairingValues,
46733
+ valueObjects,
46720
46734
  deltaObjects
46721
46735
  }) {
46722
- const rankedMatchUpValues = Object.assign(
46736
+ const pairingValueMap = Object.assign(
46723
46737
  {},
46724
46738
  ...valueSortedPairings.map((rm) => ({ [rm.pairing]: rm.value }))
46725
46739
  );
46726
- let candidate = roundCandidate({
46727
- rankedMatchUpValues,
46740
+ const actors = Object.keys(pairingValues);
46741
+ let proposedCandidates = [];
46742
+ const initialProposal = roundCandidate({
46743
+ actorsCount: actors.length,
46728
46744
  valueSortedPairings,
46729
- deltaObjects
46745
+ pairingValueMap,
46746
+ deltaObjects,
46747
+ valueObjects
46730
46748
  });
46731
- let deltaCandidate = candidate;
46732
- const actors = Object.keys(pairingValues);
46749
+ const candidateHashes = [candidateHash(initialProposal)];
46750
+ proposedCandidates.push(initialProposal);
46751
+ let lowCandidateValue = initialProposal.value;
46752
+ let deltaCandidate = initialProposal;
46733
46753
  let candidatesCount = 0;
46734
- let iterations;
46754
+ let iterations = 0;
46735
46755
  let opponentCount = actors.length;
46756
+ let calculatedIterations;
46736
46757
  do {
46737
46758
  opponentCount -= 1;
46738
- iterations = actors.length * opponentCount * valueSortedPairings.length / 2;
46739
- } while (iterations > maxIterations && opponentCount > 2);
46759
+ calculatedIterations = actors.length * pairingValues[actors[0]].length;
46760
+ } while (calculatedIterations > maxIterations && opponentCount > 5);
46740
46761
  const stipulatedPairs = [];
46741
46762
  actors.forEach((actor) => {
46742
46763
  const participantIdPairings = pairingValues[actor];
46743
46764
  participantIdPairings.slice(0, opponentCount).forEach((pairing) => {
46765
+ iterations += 1;
46744
46766
  const stipulatedPair = pairingHash(actor, pairing.opponent);
46745
46767
  if (!stipulatedPairs.includes(stipulatedPair)) {
46746
46768
  const proposed = roundCandidate({
46747
46769
  // each roundCandidate starts with stipulated pairings
46748
46770
  stipulated: [[actor, pairing.opponent]],
46749
- rankedMatchUpValues,
46771
+ actorsCount: actors.length,
46750
46772
  valueSortedPairings,
46751
- deltaObjects
46773
+ pairingValueMap,
46774
+ deltaObjects,
46775
+ valueObjects
46752
46776
  });
46753
- if (proposed.maxDelta < deltaCandidate.maxDelta)
46754
- deltaCandidate = proposed;
46755
- if (proposed.value < candidate.value)
46756
- candidate = proposed;
46757
- stipulatedPairs.push(stipulatedPair);
46758
- candidatesCount += 1;
46777
+ if (!candidateHashes.includes(candidateHash(proposed))) {
46778
+ candidateHashes.push(candidateHash(proposed));
46779
+ proposedCandidates.push(proposed);
46780
+ const { maxDelta, value } = proposed;
46781
+ if (maxDelta < deltaCandidate.maxDelta)
46782
+ deltaCandidate = proposed;
46783
+ if (value < lowCandidateValue || value === lowCandidateValue && Math.round(Math.random())) {
46784
+ lowCandidateValue = value;
46785
+ }
46786
+ stipulatedPairs.push(stipulatedPair);
46787
+ candidatesCount += 1;
46788
+ }
46759
46789
  }
46760
46790
  });
46791
+ proposedCandidates = proposedCandidates.filter(
46792
+ (proposed) => Math.abs(proposed.value - lowCandidateValue) < 5
46793
+ );
46761
46794
  });
46762
- return { candidate, deltaCandidate, candidatesCount, iterations };
46795
+ proposedCandidates.sort((a, b) => a.maxDiff - b.maxDiff);
46796
+ const candidate = randomPop(proposedCandidates);
46797
+ return {
46798
+ candidatesCount,
46799
+ deltaCandidate,
46800
+ maxIterations,
46801
+ iterations,
46802
+ candidate
46803
+ };
46804
+ }
46805
+ function candidateHash(candidate) {
46806
+ return candidate.participantIdPairings.map(({ participantIds }) => participantIds.sort().join("|")).sort().join("/");
46763
46807
  }
46764
46808
  function roundCandidate({
46765
- rankedMatchUpValues,
46766
46809
  valueSortedPairings,
46767
46810
  stipulated = [],
46768
- deltaObjects
46811
+ pairingValueMap,
46812
+ deltaObjects,
46813
+ valueObjects,
46814
+ actorsCount
46769
46815
  }) {
46770
46816
  const roundPlayers = [].concat(...stipulated);
46771
46817
  const participantIdPairings = [];
@@ -46773,11 +46819,17 @@ function roundCandidate({
46773
46819
  stipulated.filter(Boolean).forEach((participantIds) => {
46774
46820
  const [p1, p2] = participantIds;
46775
46821
  const pairing = pairingHash(p1, p2);
46776
- const value = rankedMatchUpValues[pairing];
46822
+ const value = pairingValueMap[pairing];
46777
46823
  participantIdPairings.push({ participantIds, value });
46778
- candidateValue += rankedMatchUpValues[pairing];
46824
+ candidateValue += pairingValueMap[pairing];
46779
46825
  });
46780
- valueSortedPairings.forEach((rankedPairing) => {
46826
+ const consideredPairings = chunkArray(valueSortedPairings, actorsCount).map(
46827
+ (pairings) => shuffleArray(pairings).map((pairing) => ({
46828
+ ...pairing,
46829
+ value: pairing.value + Math.random() * Math.round(Math.random())
46830
+ }))
46831
+ ).flat();
46832
+ consideredPairings.forEach((rankedPairing) => {
46781
46833
  const participantIds = rankedPairing.pairing.split("|");
46782
46834
  const opponentExists = participantIds.reduce(
46783
46835
  (p, c) => roundPlayers.includes(c) || p,
@@ -46797,17 +46849,158 @@ function roundCandidate({
46797
46849
  const delta = deltaObjects[hash];
46798
46850
  return delta > p ? delta : p;
46799
46851
  }, 0);
46800
- return { value: candidateValue, participantIdPairings, maxDelta };
46852
+ const maxDiff = participantIdPairings.reduce((p, c) => {
46853
+ const [p1, p2] = c.participantIds;
46854
+ const hash = pairingHash(p1, p2);
46855
+ const diff = valueObjects[hash];
46856
+ return diff > p ? diff : p;
46857
+ }, 0);
46858
+ return { value: candidateValue, participantIdPairings, maxDelta, maxDiff };
46801
46859
  }
46802
46860
  function pairingHash(id1, id2) {
46803
46861
  return [id1, id2].sort().join("|");
46804
46862
  }
46805
46863
 
46806
- const ENCOUNTER_VALUE = 50;
46807
- const SAME_TEAM_VALUE = 60;
46864
+ function getPairingsData({ participantIds }) {
46865
+ const possiblePairings = {};
46866
+ const uniquePairings = [];
46867
+ participantIds.forEach((participantId) => {
46868
+ possiblePairings[participantId] = participantIds.filter(
46869
+ (id) => id !== participantId
46870
+ );
46871
+ possiblePairings[participantId].forEach((id) => {
46872
+ const pairing = pairingHash(id, participantId);
46873
+ if (!uniquePairings.includes(pairing))
46874
+ uniquePairings.push(pairing);
46875
+ });
46876
+ });
46877
+ const deltaObjects = Object.assign(
46878
+ {},
46879
+ ...uniquePairings.map((pairing) => ({ [pairing]: 0 }))
46880
+ );
46881
+ return { uniquePairings, possiblePairings, deltaObjects };
46882
+ }
46883
+
46884
+ function getEncounters({ matchUps }) {
46885
+ const encounters = [];
46886
+ for (const matchUp of matchUps) {
46887
+ const participantIds = matchUp.sides.map(
46888
+ extractAttributes("participantId")
46889
+ );
46890
+ if (participantIds.length === 2) {
46891
+ const [p1, p2] = participantIds;
46892
+ const pairing = pairingHash(p1, p2);
46893
+ if (!encounters.includes(pairing))
46894
+ encounters.push(pairing);
46895
+ }
46896
+ }
46897
+ return { encounters };
46898
+ }
46899
+
46900
+ function getParticipantPairingValues({
46901
+ possiblePairings,
46902
+ valueObjects
46903
+ }) {
46904
+ const pairingValues = {};
46905
+ for (const participantId of Object.keys(possiblePairings)) {
46906
+ const participantValues = possiblePairings[participantId].map(
46907
+ (opponent) => pairingValue(participantId, opponent)
46908
+ );
46909
+ pairingValues[participantId] = participantValues.sort(
46910
+ (a, b) => a.value - b.value
46911
+ );
46912
+ }
46913
+ function pairingValue(participantId, opponent) {
46914
+ const key = pairingHash(participantId, opponent);
46915
+ return { opponent, value: valueObjects[key] };
46916
+ }
46917
+ return { pairingValues };
46918
+ }
46919
+
46808
46920
  const DEFAULT_RATING = 0;
46809
- const MAX_ITERATIONS = 5e3;
46921
+ function getSideRatings({
46922
+ tournamentParticipants,
46923
+ adHocRatings,
46924
+ eventType,
46925
+ scaleName,
46926
+ pairing
46927
+ }) {
46928
+ const defaultRating = ratingsParameters[scaleName]?.defaultInitialization ?? DEFAULT_RATING;
46929
+ return pairing.split("|").map((participantId) => {
46930
+ if (eventType === DOUBLES) {
46931
+ const individualParticipantIds = tournamentParticipants?.find(
46932
+ (participant) => participant.participantId === participantId
46933
+ )?.individualParticipantIds;
46934
+ return !individualParticipantIds ? defaultRating * 2 : individualParticipantIds?.map(
46935
+ (participantId2) => adHocRatings[participantId2] || defaultRating
46936
+ );
46937
+ } else {
46938
+ return adHocRatings[participantId] || defaultRating;
46939
+ }
46940
+ });
46941
+ }
46942
+
46943
+ function getPairings({
46944
+ tournamentParticipants,
46945
+ adHocRatings = {},
46946
+ possiblePairings,
46947
+ // participant keyed; provides array of possible opponents
46948
+ uniquePairings,
46949
+ // hashes of all possible participantId pairings
46950
+ maxIterations,
46951
+ deltaObjects,
46952
+ // difference in rating between paired participants
46953
+ valueObjects,
46954
+ // calculated value of a pairing of participants, used for sorting pairings
46955
+ eventType,
46956
+ scaleName,
46957
+ salted
46958
+ }) {
46959
+ uniquePairings.forEach((pairing) => {
46960
+ const ratings = getSideRatings({
46961
+ tournamentParticipants,
46962
+ adHocRatings,
46963
+ scaleName,
46964
+ eventType,
46965
+ pairing
46966
+ });
46967
+ const salting = typeof salted === "number" && salted || 0.5;
46968
+ const salt = salted && (Math.round(Math.random()) ? salting : salting * -1) || 0;
46969
+ const ratingsDifference = Math.abs(ratings[0] - ratings[1]) + salt;
46970
+ const pairingDelta = Math.abs(ratings[0] - ratings[1]);
46971
+ deltaObjects[pairing] = pairingDelta;
46972
+ if (!valueObjects[pairing])
46973
+ valueObjects[pairing] = 0;
46974
+ valueObjects[pairing] += ratingsDifference ? Math.pow(ratingsDifference, 2) : 0;
46975
+ });
46976
+ const valueSortedPairings = uniquePairings.map((pairing) => ({ pairing, value: valueObjects[pairing] })).sort((a, b) => a.value - b.value);
46977
+ const { pairingValues } = getParticipantPairingValues({
46978
+ possiblePairings,
46979
+ valueObjects
46980
+ });
46981
+ const { candidate, candidatesCount, deltaCandidate, iterations } = generateCandidate({
46982
+ valueSortedPairings,
46983
+ maxIterations,
46984
+ pairingValues,
46985
+ deltaObjects,
46986
+ valueObjects
46987
+ });
46988
+ const { participantIdPairings } = candidate;
46989
+ return {
46990
+ participantIdPairings,
46991
+ candidatesCount,
46992
+ deltaCandidate,
46993
+ iterations,
46994
+ candidate
46995
+ };
46996
+ }
46997
+
46998
+ const ENCOUNTER_VALUE = 100;
46999
+ const SAME_TEAM_VALUE = 100;
47000
+ const MAX_ITERATIONS = 4e3;
46810
47001
  function generateDrawMaticRound({
47002
+ encounterValue = ENCOUNTER_VALUE,
47003
+ sameTeamValue = SAME_TEAM_VALUE,
46811
47004
  maxIterations = MAX_ITERATIONS,
46812
47005
  generateMatchUps = true,
46813
47006
  tournamentParticipants,
@@ -46817,9 +47010,11 @@ function generateDrawMaticRound({
46817
47010
  drawDefinition,
46818
47011
  adHocRatings,
46819
47012
  structureId,
47013
+ salted = 0.5,
46820
47014
  matchUpIds,
46821
47015
  eventType,
46822
- structure
47016
+ structure,
47017
+ scaleName
46823
47018
  }) {
46824
47019
  if (!drawDefinition)
46825
47020
  return { error: MISSING_DRAW_DEFINITION };
@@ -46838,7 +47033,7 @@ function generateDrawMaticRound({
46838
47033
  for (const pairing of encounters) {
46839
47034
  if (!valueObjects[pairing])
46840
47035
  valueObjects[pairing] = 0;
46841
- valueObjects[pairing] += ENCOUNTER_VALUE;
47036
+ valueObjects[pairing] += encounterValue;
46842
47037
  }
46843
47038
  const teamParticipants = tournamentParticipants?.filter(
46844
47039
  ({ participantType }) => participantType === TEAM
@@ -46850,7 +47045,7 @@ function generateDrawMaticRound({
46850
47045
  for (const pairing of uniquePairings2) {
46851
47046
  if (!valueObjects[pairing])
46852
47047
  valueObjects[pairing] = 0;
46853
- valueObjects[pairing] += SAME_TEAM_VALUE;
47048
+ valueObjects[pairing] += sameTeamValue;
46854
47049
  }
46855
47050
  }
46856
47051
  }
@@ -46868,9 +47063,11 @@ function generateDrawMaticRound({
46868
47063
  deltaObjects,
46869
47064
  valueObjects,
46870
47065
  eventType,
46871
- structure
47066
+ scaleName,
47067
+ structure,
47068
+ salted
46872
47069
  };
46873
- const { candidatesCount, participantIdPairings, iterations } = getPairings(params);
47070
+ const { candidatesCount, participantIdPairings, iterations, candidate } = getPairings(params);
46874
47071
  if (!candidatesCount)
46875
47072
  return { error: NO_CANDIDATES };
46876
47073
  let matchUps;
@@ -46888,130 +47085,28 @@ function generateDrawMaticRound({
46888
47085
  return result;
46889
47086
  matchUps = result.matchUps;
46890
47087
  }
47088
+ const { maxDelta, maxDiff } = candidate;
46891
47089
  return {
46892
47090
  ...SUCCESS,
46893
47091
  participantIdPairings,
46894
47092
  candidatesCount,
46895
47093
  iterations,
46896
- matchUps
47094
+ matchUps,
47095
+ maxDelta,
47096
+ maxDiff
46897
47097
  };
46898
47098
  }
46899
- function getSideRatings({
46900
- tournamentParticipants,
46901
- adHocRatings,
46902
- eventType,
46903
- pairing
46904
- }) {
46905
- return pairing.split("|").map((participantId) => {
46906
- if (eventType === DOUBLES) {
46907
- const individualParticipantIds = tournamentParticipants?.find(
46908
- (participant) => participant.participantId === participantId
46909
- )?.individualParticipantIds;
46910
- return !individualParticipantIds ? DEFAULT_RATING * 2 : individualParticipantIds?.map(
46911
- (participantId2) => adHocRatings[participantId2 || DEFAULT_RATING]
46912
- );
46913
- } else {
46914
- return adHocRatings[participantId] || DEFAULT_RATING;
46915
- }
46916
- });
46917
- }
46918
- function getPairings({
46919
- tournamentParticipants,
46920
- adHocRatings = {},
46921
- possiblePairings,
46922
- // participant keyed; provides array of possible opponents
46923
- uniquePairings,
46924
- // hashes of all possible participantId pairings
46925
- maxIterations,
46926
- deltaObjects,
46927
- // difference in rating between paired participants
46928
- valueObjects,
46929
- // calculated value of a pairing of participants, used for sorting pairings
46930
- eventType
46931
- }) {
46932
- uniquePairings.forEach((pairing) => {
46933
- const ratings = getSideRatings({
46934
- tournamentParticipants,
46935
- adHocRatings,
46936
- eventType,
46937
- pairing
46938
- });
46939
- const ratingsDifference = Math.abs(ratings[0] - ratings[1]) + 1;
46940
- deltaObjects[pairing] = Math.abs(ratings[0] - ratings[1]);
46941
- if (!valueObjects[pairing])
46942
- valueObjects[pairing] = 0;
46943
- valueObjects[pairing] += Math.pow(ratingsDifference, 2);
46944
- });
46945
- const valueSortedPairings = uniquePairings.map((pairing) => ({ pairing, value: valueObjects[pairing] })).sort((a, b) => a.value - b.value);
46946
- const { pairingValues } = getParticipantPairingValues({
46947
- possiblePairings,
46948
- valueObjects
46949
- });
46950
- const { candidate, candidatesCount, iterations } = generateCandidate({
46951
- valueSortedPairings,
46952
- maxIterations,
46953
- pairingValues,
46954
- deltaObjects
46955
- });
46956
- const { participantIdPairings } = candidate;
46957
- return { candidatesCount, participantIdPairings, iterations };
46958
- }
46959
- function getPairingsData({ participantIds }) {
46960
- const possiblePairings = {};
46961
- const uniquePairings = [];
46962
- participantIds.forEach((participantId) => {
46963
- possiblePairings[participantId] = participantIds.filter(
46964
- (id) => id !== participantId
46965
- );
46966
- possiblePairings[participantId].forEach((id) => {
46967
- const pairing = pairingHash(id, participantId);
46968
- if (!uniquePairings.includes(pairing))
46969
- uniquePairings.push(pairing);
46970
- });
46971
- });
46972
- const deltaObjects = Object.assign(
46973
- {},
46974
- ...uniquePairings.map((pairing) => ({ [pairing]: 0 }))
46975
- );
46976
- return { uniquePairings, possiblePairings, deltaObjects };
46977
- }
46978
- function getEncounters({ matchUps }) {
46979
- const encounters = [];
46980
- for (const matchUp of matchUps) {
46981
- const participantIds = matchUp.sides.map(getParticipantId);
46982
- if (participantIds.length === 2) {
46983
- const [p1, p2] = participantIds;
46984
- const pairing = pairingHash(p1, p2);
46985
- if (!encounters.includes(pairing))
46986
- encounters.push(pairing);
46987
- }
46988
- }
46989
- return { encounters };
46990
- }
46991
- function getParticipantPairingValues({ possiblePairings, valueObjects }) {
46992
- const pairingValues = {};
46993
- for (const participantId of Object.keys(possiblePairings)) {
46994
- const participantValues = possiblePairings[participantId].map(
46995
- (opponent) => pairingValue(participantId, opponent)
46996
- );
46997
- pairingValues[participantId] = participantValues.sort(
46998
- (a, b) => a.value - b.value
46999
- );
47000
- }
47001
- function pairingValue(participantId, opponent) {
47002
- const key = pairingHash(participantId, opponent);
47003
- return { opponent, value: valueObjects[key] };
47004
- }
47005
- return { pairingValues };
47006
- }
47007
47099
 
47008
47100
  function drawMatic$1({
47009
47101
  tournamentParticipants,
47010
47102
  restrictEntryStatus,
47011
- tournamentRecord,
47103
+ adHocRatings = {},
47012
47104
  generateMatchUps,
47105
+ tournamentRecord,
47013
47106
  addToStructure,
47014
47107
  participantIds,
47108
+ encounterValue,
47109
+ sameTeamValue,
47015
47110
  drawDefinition,
47016
47111
  scaleAccessor,
47017
47112
  maxIterations,
@@ -47020,6 +47115,7 @@ function drawMatic$1({
47020
47115
  scaleName,
47021
47116
  // custom rating name to seed dynamic ratings
47022
47117
  eventType,
47118
+ salted,
47023
47119
  event
47024
47120
  }) {
47025
47121
  if (typeof drawDefinition !== "object" || drawDefinition.drawType && drawDefinition.drawType !== AD_HOC) {
@@ -47062,12 +47158,16 @@ function drawMatic$1({
47062
47158
  if (!structureIsAdHoc)
47063
47159
  return { error: INVALID_DRAW_DEFINITION };
47064
47160
  tournamentParticipants = tournamentParticipants ?? tournamentRecord.participants ?? [];
47065
- const adHocRatings = {};
47066
47161
  for (const participantId of participantIds ?? []) {
47067
47162
  const participant = tournamentParticipants?.find(
47068
47163
  (participant2) => participant2.participantId === participantId
47069
47164
  );
47070
- let scaleValue = getScaleValue({ eventType, participant });
47165
+ let scaleValue = getScaleValue({
47166
+ scaleName: `${scaleName}.${DYNAMIC}`,
47167
+ scaleAccessor,
47168
+ participant,
47169
+ eventType
47170
+ });
47071
47171
  if (!scaleValue && scaleName) {
47072
47172
  scaleValue = getScaleValue({
47073
47173
  scaleAccessor,
@@ -47076,32 +47176,36 @@ function drawMatic$1({
47076
47176
  eventType
47077
47177
  });
47078
47178
  }
47079
- if (scaleValue)
47179
+ if (scaleValue && !adHocRatings[participantId])
47080
47180
  adHocRatings[participantId] = scaleValue;
47081
47181
  }
47082
47182
  return generateDrawMaticRound({
47083
47183
  tournamentParticipants,
47084
- tournamentRecord,
47085
47184
  generateMatchUps,
47086
- participantIds,
47185
+ tournamentRecord,
47087
47186
  addToStructure,
47187
+ participantIds,
47188
+ encounterValue,
47189
+ sameTeamValue,
47088
47190
  drawDefinition,
47089
47191
  maxIterations,
47090
47192
  adHocRatings,
47091
47193
  matchUpIds,
47092
47194
  structure,
47093
- eventType
47195
+ eventType,
47196
+ salted
47094
47197
  });
47095
47198
  }
47096
47199
  function getScaleValue({
47097
- eventType = TypeEnum.Singles,
47098
- scaleName = "dynamic",
47200
+ scaleType = RATING$2,
47099
47201
  scaleAccessor,
47100
- participant
47202
+ participant,
47203
+ scaleName,
47204
+ eventType
47101
47205
  }) {
47102
47206
  const scaleAttributes = {
47103
47207
  eventType: eventType || TypeEnum.Singles,
47104
- scaleType: RATING$2,
47208
+ scaleType,
47105
47209
  scaleName
47106
47210
  };
47107
47211
  const result = participant && participantScaleItem({
@@ -59475,11 +59579,15 @@ function calculateNewRatings(params) {
59475
59579
  targetRange: consideredRange
59476
59580
  });
59477
59581
  const updatedWinnerRating = invertedScale ? ratingRange[0] - convertedUpdatedWinnerRating : convertedUpdatedWinnerRating;
59478
- let newWinnerRating = parseFloat(updatedWinnerRating).toFixed(decimalPlaces);
59582
+ let newWinnerRating = parseFloat(
59583
+ parseFloat(updatedWinnerRating).toFixed(decimalPlaces)
59584
+ );
59479
59585
  const updatedLoserRating = invertedScale ? ratingRange[0] - convertedUpdatedLoserRating : convertedUpdatedLoserRating;
59480
- let newLoserRating = parseFloat(updatedLoserRating).toFixed(decimalPlaces);
59586
+ let newLoserRating = parseFloat(
59587
+ parseFloat(updatedLoserRating).toFixed(decimalPlaces)
59588
+ );
59481
59589
  const percentageDifference = Math.max(...ratingRange) ? Math.abs(winnerRating - loserRating) / Math.max(...ratingRange) : 0;
59482
- if (convertedUpdatedWinnerRating > convertedUpdatedLoserRating && percentageDifference > eloConfig.diffThreshold || parseFloat(newWinnerRating) < 0 || parseFloat(newLoserRating) < 0) {
59590
+ if (convertedUpdatedWinnerRating > convertedUpdatedLoserRating && percentageDifference > eloConfig.diffThreshold || newWinnerRating < 0 || newLoserRating < 0) {
59483
59591
  newWinnerRating = winnerRating;
59484
59592
  newLoserRating = loserRating;
59485
59593
  }
@@ -59497,7 +59605,8 @@ const aggregateSets = (sets) => {
59497
59605
  ) || [0, 0];
59498
59606
  };
59499
59607
 
59500
- function processMatchUps({
59608
+ function generateDynamicRatings({
59609
+ removePriorValues = true,
59501
59610
  tournamentRecord,
59502
59611
  ratingType = ELO,
59503
59612
  considerGames,
@@ -59528,7 +59637,7 @@ function processMatchUps({
59528
59637
  scaleName: ratingType,
59529
59638
  scaleType: RATING$2
59530
59639
  };
59531
- const dynamicScaleName = `${ratingType}.DYNAMIC`;
59640
+ const dynamicScaleName = `${ratingType}.${DYNAMIC}`;
59532
59641
  const dynamicScaleAttributes = {
59533
59642
  scaleName: dynamicScaleName,
59534
59643
  eventType: matchUpType,
@@ -59564,9 +59673,9 @@ function processMatchUps({
59564
59673
  return participantId && {
59565
59674
  [participantId]: dynamicScaleItem ?? scaleItem ?? {
59566
59675
  scaleName: outputScaleName,
59567
- scaleType: RATING$2,
59568
59676
  eventType: matchUpType,
59569
59677
  scaleDate: endDate,
59678
+ scaleType: RATING$2,
59570
59679
  scaleValue
59571
59680
  }
59572
59681
  };
@@ -59595,27 +59704,35 @@ function processMatchUps({
59595
59704
  loserRating,
59596
59705
  ratingType
59597
59706
  });
59598
- const newWinnerScaleValue = accessor ? { ...winnerScaleValue, [accessor]: newWinnerRating } : newWinnerRating;
59599
- const newLoserScaleValue = accessor ? { ...loserScaleValue, [accessor]: newLoserRating } : newLoserRating;
59707
+ const newWinnerScaleValue = accessor ? {
59708
+ ...winnerScaleValue,
59709
+ [accessor]: newWinnerRating
59710
+ } : newWinnerRating;
59711
+ const newLoserScaleValue = accessor ? {
59712
+ ...loserScaleValue,
59713
+ [accessor]: newLoserRating
59714
+ } : newLoserRating;
59600
59715
  scaleItemMap[winnerParticipantId].scaleValue = newWinnerScaleValue;
59601
59716
  scaleItemMap[loserParticipantId].scaleValue = newLoserScaleValue;
59602
59717
  let result = setParticipantScaleItem({
59718
+ participantId: winnerParticipantId,
59719
+ removePriorValues,
59720
+ tournamentRecord,
59603
59721
  scaleItem: {
59604
59722
  ...scaleItemMap[winnerParticipantId],
59605
59723
  scaleName: outputScaleName
59606
- },
59607
- participantId: winnerParticipantId,
59608
- tournamentRecord
59724
+ }
59609
59725
  });
59610
59726
  if (result.error)
59611
59727
  return result;
59612
59728
  result = setParticipantScaleItem({
59729
+ participantId: loserParticipantId,
59730
+ removePriorValues,
59731
+ tournamentRecord,
59613
59732
  scaleItem: {
59614
59733
  ...scaleItemMap[loserParticipantId],
59615
59734
  scaleName: outputScaleName
59616
- },
59617
- participantId: loserParticipantId,
59618
- tournamentRecord
59735
+ }
59619
59736
  });
59620
59737
  if (result.error)
59621
59738
  return result;
@@ -59629,7 +59746,7 @@ function processMatchUps({
59629
59746
 
59630
59747
  const governor = {
59631
59748
  calculateNewRatings,
59632
- processMatchUps
59749
+ generateDynamicRatings
59633
59750
  };
59634
59751
 
59635
59752
  const scaleEngine = (() => {