tods-competition-factory 2.0.37 → 2.0.40

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.0.37';
6
+ return '2.0.40';
7
7
  }
8
8
 
9
9
  function isFunction(obj) {
@@ -1256,6 +1256,9 @@ function skewedDistribution(min, max, skew, step, significantDecimals = 2) {
1256
1256
  num = stepRound(num, step);
1257
1257
  return parseFloat(num.toFixed(significantDecimals));
1258
1258
  }
1259
+ function fixedDecimals(value, to = 2) {
1260
+ return parseFloat(Number(Math.round(value * 1000) / 1000).toFixed(to));
1261
+ }
1259
1262
 
1260
1263
  function unique(arr) {
1261
1264
  if (!Array.isArray(arr))
@@ -19702,6 +19705,153 @@ function generateAndPopulateRRplayoffStructures(params) {
19702
19705
  };
19703
19706
  }
19704
19707
 
19708
+ function convertRange({ value, sourceRange, targetRange }) {
19709
+ const minSourceRange = Math.min(...sourceRange);
19710
+ const maxSourceRange = Math.max(...sourceRange);
19711
+ const minTargetRange = Math.min(...targetRange);
19712
+ const maxTargetRange = Math.max(...targetRange);
19713
+ return (((value - minSourceRange) * (maxTargetRange - minTargetRange)) / (maxSourceRange - minSourceRange) + minTargetRange);
19714
+ }
19715
+
19716
+ const ELO = 'ELO';
19717
+ const NTRP = 'NTRP';
19718
+ const TRN = 'TRN';
19719
+ const UTR = 'UTR';
19720
+ const WTN = 'WTN';
19721
+ const ratingConstants = {
19722
+ ELO,
19723
+ NTRP,
19724
+ TRN,
19725
+ UTR,
19726
+ WTN,
19727
+ };
19728
+
19729
+ const ratingsParameters = {
19730
+ [ELO]: {
19731
+ defaultInitialization: 1500,
19732
+ decimalsCount: 0,
19733
+ range: [0, 3000],
19734
+ ascending: true,
19735
+ },
19736
+ [NTRP]: {
19737
+ accessors: ['ntrpRating', 'dntrpRatingHundredths'],
19738
+ attributes: { ustaRatingType: '' },
19739
+ accessor: 'dntrpRatingHundredths',
19740
+ defaultInitialization: 3,
19741
+ decimalsCount: 1,
19742
+ ascending: true,
19743
+ range: [1, 7],
19744
+ },
19745
+ [UTR]: {
19746
+ defaultInitialization: 6,
19747
+ accessors: ['utrRating'],
19748
+ accessor: 'utrRating',
19749
+ decimalsCount: 2,
19750
+ ascending: true,
19751
+ range: [1, 16],
19752
+ },
19753
+ [WTN]: {
19754
+ attributes: { confidence: { generator: true, range: [60, 100] } },
19755
+ accessors: ['wtnRating', 'confidence'],
19756
+ defaultInitialization: 23,
19757
+ accessor: 'wtnRating',
19758
+ ascending: false,
19759
+ decimalsCount: 2,
19760
+ range: [40, 1],
19761
+ },
19762
+ };
19763
+
19764
+ function getRatingConvertedToELO({ sourceRatingType, sourceRating }) {
19765
+ const sourceRatingRange = ratingsParameters[sourceRatingType].range;
19766
+ const invertedScale = sourceRatingRange[0] > sourceRatingRange[1];
19767
+ const eloRatingRange = ratingsParameters[ELO].range;
19768
+ return convertRange({
19769
+ value: invertedScale ? sourceRatingRange[0] - sourceRating : sourceRating,
19770
+ sourceRange: sourceRatingRange,
19771
+ targetRange: eloRatingRange,
19772
+ });
19773
+ }
19774
+ function getRatingConvertedFromELO({ targetRatingType, sourceRating }) {
19775
+ const decimalPlaces = ratingsParameters[targetRatingType].decimalsCount || 0;
19776
+ const targetRatingRange = ratingsParameters[targetRatingType].range;
19777
+ const invertedScale = targetRatingRange[0] > targetRatingRange[1];
19778
+ const maxTargetRatingRange = Math.max(...targetRatingRange);
19779
+ const eloRatingRange = ratingsParameters[ELO].range;
19780
+ const result = convertRange({
19781
+ targetRange: targetRatingRange,
19782
+ sourceRange: eloRatingRange,
19783
+ value: sourceRating,
19784
+ });
19785
+ const convertedRating = parseFloat(result.toFixed(decimalPlaces));
19786
+ return invertedScale ? maxTargetRatingRange - convertedRating : convertedRating;
19787
+ }
19788
+
19789
+ function getConvertedRating(params) {
19790
+ const paramsCheck = checkRequiredParameters(params, [{ ratings: true, [OF_TYPE]: OBJECT }]);
19791
+ if (paramsCheck.error)
19792
+ return paramsCheck;
19793
+ const matchUpType = params.matchUpType && [SINGLES, DOUBLES].includes(params.matchUpType) ? params.matchUpType : SINGLES;
19794
+ const ratingTypes = Object.keys(ratingsParameters);
19795
+ const targetRatingType = params.targetRatingType && ratingTypes.includes(params.targetRatingType) ? params.targetRatingType : ELO;
19796
+ const sourceRatings = params.ratings[matchUpType]
19797
+ ? params.ratings[matchUpType].reduce((sr, rating) => (sr.includes(rating.scaleName) ? sr : sr.concat(rating.scaleName)), [])
19798
+ : [];
19799
+ if (!sourceRatings)
19800
+ return { error: NOT_FOUND };
19801
+ const sourceRatingObject = params.ratings[matchUpType]?.find((rating) => rating.scaleName === targetRatingType) ??
19802
+ params.ratings[matchUpType][0];
19803
+ if (sourceRatings[0] === targetRatingType)
19804
+ return sourceRatingObject;
19805
+ const sourceRatingType = sourceRatingObject.scaleName;
19806
+ const accessor = ratingsParameters[sourceRatingObject.scaleName].accessor;
19807
+ const sourceRating = accessor ? sourceRatingObject.scaleValue[accessor] : sourceRatingObject.scaleValue;
19808
+ const eloValue = getRatingConvertedToELO({ sourceRatingType, sourceRating });
19809
+ const convertedRating = getRatingConvertedFromELO({
19810
+ targetRatingType: targetRatingType,
19811
+ sourceRating: eloValue,
19812
+ });
19813
+ return { convertedRating, sourceRating };
19814
+ }
19815
+
19816
+ function calculatePressureRatings({ participantResults, sides, score }) {
19817
+ const side1 = sides.find(({ sideNumber }) => sideNumber === 1);
19818
+ const side2 = sides.find(({ sideNumber }) => sideNumber === 2);
19819
+ const side1ratings = side1?.participant?.ratings;
19820
+ const side2ratings = side2?.participant?.ratings;
19821
+ if (side1ratings[SINGLES] && side2ratings[SINGLES]) {
19822
+ const targetRatingType = ELO;
19823
+ const { convertedRating: side1ConvertedRating } = getConvertedRating({ ratings: side1ratings, targetRatingType });
19824
+ const { convertedRating: side2ConvertedRating } = getConvertedRating({ ratings: side2ratings, targetRatingType });
19825
+ const { side1pressure, side2pressure } = getSideValues$1({ side1ConvertedRating, side2ConvertedRating, score });
19826
+ participantResults[side1?.participantId].pressureScores.push(side1pressure);
19827
+ participantResults[side2?.participantId].pressureScores.push(side2pressure);
19828
+ const highRange = Math.max(...ratingsParameters[ELO].range);
19829
+ const side1Variation = fixedDecimals((side2ConvertedRating - side1ConvertedRating) / highRange);
19830
+ const side2Variation = fixedDecimals((side1ConvertedRating - side2ConvertedRating) / highRange);
19831
+ participantResults[side1?.participantId].ratingVariation.push(side1Variation);
19832
+ participantResults[side2?.participantId].ratingVariation.push(side2Variation);
19833
+ }
19834
+ }
19835
+ function getSideValues$1({ side1ConvertedRating, side2ConvertedRating, score }) {
19836
+ const highRating = side1ConvertedRating > side2ConvertedRating ? side1ConvertedRating : side2ConvertedRating;
19837
+ const lowRating = side1ConvertedRating > side2ConvertedRating ? side2ConvertedRating : side1ConvertedRating;
19838
+ const ratingsDifference = Math.abs(side1ConvertedRating - side2ConvertedRating);
19839
+ const eloRatingRange = ratingsParameters[ELO].range;
19840
+ const rangeMax = Math.max(...eloRatingRange);
19841
+ const bumpBump = (rangeMax - highRating) * 0;
19842
+ const discount = (highRating + bumpBump) / rangeMax;
19843
+ const lowSideBump = discount * ratingsDifference;
19844
+ const gamesWonSide1 = score?.sets?.reduce((total, set) => total + (set?.side1Score ?? 0), 0);
19845
+ const gamesWonSide2 = score?.sets?.reduce((total, set) => total + (set.side2Score ?? 0), 0);
19846
+ const lowSide = side1ConvertedRating > side2ConvertedRating ? 2 : 1;
19847
+ const side1value = gamesWonSide1 * (lowRating + (lowSide === 1 ? lowSideBump : 0));
19848
+ const side2value = gamesWonSide2 * (lowRating + (lowSide === 2 ? lowSideBump : 0));
19849
+ const combinedValues = side1value + side2value;
19850
+ const side1pressure = fixedDecimals(side1value / combinedValues);
19851
+ const side2pressure = fixedDecimals(side2value / combinedValues);
19852
+ return { side1pressure, side2pressure };
19853
+ }
19854
+
19705
19855
  const FORMAT_STANDARD = 'SET3-S:6/TB7';
19706
19856
  const FORMAT_STANDARD_NOAD = 'SET3-S:6NOAD';
19707
19857
  const FORMAT_ATP_DOUBLES = 'SET3-S:6/TB7-F:TB10';
@@ -19907,108 +20057,6 @@ function calculatePercentages({ participantResults, matchUpFormat, tallyPolicy,
19907
20057
  });
19908
20058
  }
19909
20059
 
19910
- const ELO = 'ELO';
19911
- const NTRP = 'NTRP';
19912
- const TRN = 'TRN';
19913
- const UTR = 'UTR';
19914
- const WTN = 'WTN';
19915
- const ratingConstants = {
19916
- ELO,
19917
- NTRP,
19918
- TRN,
19919
- UTR,
19920
- WTN,
19921
- };
19922
-
19923
- const ratingsParameters = {
19924
- [ELO]: {
19925
- defaultInitialization: 1500,
19926
- decimalsCount: 0,
19927
- range: [0, 3000],
19928
- ascending: true,
19929
- },
19930
- [NTRP]: {
19931
- accessors: ['ntrpRating', 'dntrpRatingHundredths'],
19932
- attributes: { ustaRatingType: '' },
19933
- accessor: 'dntrpRatingHundredths',
19934
- defaultInitialization: 3,
19935
- decimalsCount: 1,
19936
- ascending: true,
19937
- range: [1, 7],
19938
- },
19939
- [UTR]: {
19940
- defaultInitialization: 6,
19941
- accessors: ['utrRating'],
19942
- accessor: 'utrRating',
19943
- decimalsCount: 2,
19944
- ascending: true,
19945
- range: [1, 16],
19946
- },
19947
- [WTN]: {
19948
- attributes: { confidence: { generator: true, range: [60, 100] } },
19949
- accessors: ['wtnRating', 'confidence'],
19950
- defaultInitialization: 23,
19951
- accessor: 'wtnRating',
19952
- ascending: false,
19953
- decimalsCount: 2,
19954
- range: [40, 1],
19955
- },
19956
- };
19957
-
19958
- function convertRange({ value, sourceRange, targetRange }) {
19959
- return (((value - sourceRange[0]) * (targetRange[1] - targetRange[0])) / (sourceRange[1] - sourceRange[0]) + targetRange[0]);
19960
- }
19961
-
19962
- function getRatingConvertedToELO({ sourceRatingType, sourceRating }) {
19963
- const sourceRatingRange = ratingsParameters[sourceRatingType].range;
19964
- const invertedScale = sourceRatingRange[0] > sourceRatingRange[1];
19965
- const eloRatingRange = ratingsParameters[ELO].range;
19966
- return convertRange({
19967
- value: invertedScale ? sourceRatingRange[0] - sourceRating : sourceRating,
19968
- sourceRange: sourceRatingRange,
19969
- targetRange: eloRatingRange,
19970
- });
19971
- }
19972
- function getRatingConvertedFromELO({ targetRatingType, sourceRating }) {
19973
- const decimalPlaces = ratingsParameters[targetRatingType].decimalsCount || 0;
19974
- const targetRatingRange = ratingsParameters[targetRatingType].range;
19975
- const invertedScale = targetRatingRange[0] > targetRatingRange[1];
19976
- const eloRatingRange = ratingsParameters[ELO].range;
19977
- const result = convertRange({
19978
- targetRange: targetRatingRange,
19979
- sourceRange: eloRatingRange,
19980
- value: sourceRating,
19981
- });
19982
- const convertedRating = parseFloat(parseFloat(result).toFixed(decimalPlaces));
19983
- return invertedScale ? targetRatingRange[0] - convertedRating : convertedRating;
19984
- }
19985
-
19986
- function getConvertedRating(params) {
19987
- const paramsCheck = checkRequiredParameters(params, [{ ratings: true, [OF_TYPE]: OBJECT }]);
19988
- if (paramsCheck.error)
19989
- return paramsCheck;
19990
- const matchUpType = params.matchUpType && [SINGLES, DOUBLES].includes(params.matchUpType) ? params.matchUpType : SINGLES;
19991
- const ratingTypes = Object.keys(ratingsParameters);
19992
- const targetRatingType = params.targetRatingType && ratingTypes.includes(params.targetRatingType) ? params.targetRatingType : ELO;
19993
- const sourceRatings = params.ratings[matchUpType]
19994
- ? params.ratings[matchUpType].reduce((sr, rating) => (sr.includes(rating.scaleName) ? sr : sr.concat(rating.scaleName)), [])
19995
- : [];
19996
- if (!sourceRatings)
19997
- return { error: NOT_FOUND };
19998
- const sourceRatingObject = params.ratings[matchUpType]?.find((rating) => rating.scaleName === targetRatingType) ??
19999
- params.ratings[matchUpType][0];
20000
- if (sourceRatings[0] === targetRatingType)
20001
- return sourceRatingObject;
20002
- const accessor = ratingsParameters[sourceRatingObject.scaleName].accessor;
20003
- const value = accessor ? sourceRatingObject.scaleValue[accessor] : sourceRatingObject.scaleValue;
20004
- const eloValue = getRatingConvertedToELO({ sourceRatingType: sourceRatingObject.scaleName, sourceRating: value });
20005
- const convertedRating = getRatingConvertedFromELO({
20006
- targetRatingType: targetRatingType,
20007
- sourceRating: eloValue,
20008
- });
20009
- return { convertedRating };
20010
- }
20011
-
20012
20060
  function getParticipantResults({ participantIds, pressureRating, matchUpFormat, tallyPolicy, perPlayer, matchUps, }) {
20013
20061
  const participantResults = {};
20014
20062
  const excludeMatchUpStatuses = tallyPolicy?.excludeMatchUpStatuses || [];
@@ -20128,6 +20176,7 @@ function getParticipantResults({ participantIds, pressureRating, matchUpFormat,
20128
20176
  processMatchUp({
20129
20177
  matchUpFormat: tieMatchUp.matchUpFormat,
20130
20178
  matchUpStatus: tieMatchUp.matchUpStatus,
20179
+ matchUpType: tieMatchUp.matchUpType,
20131
20180
  score: tieMatchUp.score,
20132
20181
  sides: tieMatchUp.sides,
20133
20182
  winningParticipantId,
@@ -20150,6 +20199,7 @@ function getParticipantResults({ participantIds, pressureRating, matchUpFormat,
20150
20199
  else {
20151
20200
  processMatchUp({
20152
20201
  matchUpFormat: matchUp.matchUpFormat ?? matchUpFormat,
20202
+ matchUpType: matchUp.matchUpType,
20153
20203
  isTieMatchUp: undefined,
20154
20204
  winningParticipantId,
20155
20205
  manualGamesOverride,
@@ -20263,24 +20313,11 @@ function processScore({ manualGamesOverride, participantResults, score, sides })
20263
20313
  }
20264
20314
  });
20265
20315
  }
20266
- function processMatchUp({ winningParticipantId, manualGamesOverride, losingParticipantId, participantResults, pressureRating, matchUpFormat, matchUpStatus, isTieMatchUp, tallyPolicy, winningSide, score, sides, }) {
20316
+ function processMatchUp({ winningParticipantId, manualGamesOverride, losingParticipantId, participantResults, pressureRating, matchUpFormat, matchUpStatus, isTieMatchUp, matchUpType, tallyPolicy, winningSide, score, sides, }) {
20267
20317
  const winningSideIndex = winningSide && winningSide - 1;
20268
20318
  const losingSideIndex = 1 - winningSideIndex;
20269
- if (pressureRating) {
20270
- const fixed2 = (value) => parseFloat(Number(Math.round(value * 1000) / 1000).toFixed(2));
20271
- const gamesWonSide1 = score?.sets?.reduce((total, set) => total + (set?.side1Score ?? 0), 0);
20272
- const gamesWonSide2 = score?.sets?.reduce((total, set) => total + (set.side2Score ?? 0), 0);
20273
- const side1 = sides.find(({ sideNumber }) => sideNumber === 1);
20274
- const side2 = sides.find(({ sideNumber }) => sideNumber === 2);
20275
- const side1ConvertedRating = getConvertedRating({ ratings: side1?.participant?.ratings }).convertedRating;
20276
- const side2ConvertedRating = getConvertedRating({ ratings: side2?.participant?.ratings }).convertedRating;
20277
- const side1Value = gamesWonSide1 * side2ConvertedRating;
20278
- const side2Value = gamesWonSide2 * side1ConvertedRating;
20279
- participantResults[side1?.participantId].pressureScores.push(fixed2(side1Value / (side1Value + side2Value)));
20280
- participantResults[side2?.participantId].pressureScores.push(fixed2(side2Value / (side1Value + side2Value)));
20281
- const highRange = Math.max(...ratingsParameters[ELO].range);
20282
- participantResults[side1?.participantId].ratingVariation.push(fixed2((side1ConvertedRating - side2ConvertedRating) / highRange));
20283
- participantResults[side2?.participantId].ratingVariation.push(fixed2((side2ConvertedRating - side1ConvertedRating) / highRange));
20319
+ if (pressureRating && matchUpType === SINGLES) {
20320
+ calculatePressureRatings({ participantResults, sides, score });
20284
20321
  }
20285
20322
  if (!isTieMatchUp) {
20286
20323
  processOutcome$1({
@@ -26536,9 +26573,9 @@ function calculateNewRatings(params) {
26536
26573
  const updatedWinnerRating = invertedScale
26537
26574
  ? ratingRange[0] - convertedUpdatedWinnerRating
26538
26575
  : convertedUpdatedWinnerRating;
26539
- let newWinnerRating = parseFloat(parseFloat(updatedWinnerRating).toFixed(decimalPlaces));
26576
+ let newWinnerRating = parseFloat(updatedWinnerRating.toFixed(decimalPlaces));
26540
26577
  const updatedLoserRating = invertedScale ? ratingRange[0] - convertedUpdatedLoserRating : convertedUpdatedLoserRating;
26541
- let newLoserRating = parseFloat(parseFloat(updatedLoserRating).toFixed(decimalPlaces));
26578
+ let newLoserRating = parseFloat(updatedLoserRating.toFixed(decimalPlaces));
26542
26579
  const percentageDifference = Math.max(...ratingRange)
26543
26580
  ? Math.abs(winnerRating - loserRating) / Math.max(...ratingRange)
26544
26581
  : 0;