tods-competition-factory 2.0.39 → 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.39';
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,114 +20057,6 @@ function calculatePercentages({ participantResults, matchUpFormat, tallyPolicy,
19907
20057
  });
19908
20058
  }
19909
20059
 
19910
- function convertRange({ value, sourceRange, targetRange }) {
19911
- const minSourceRange = Math.min(...sourceRange);
19912
- const maxSourceRange = Math.max(...sourceRange);
19913
- const minTargetRange = Math.min(...targetRange);
19914
- const maxTargetRange = Math.max(...targetRange);
19915
- return (((value - minSourceRange) * (maxTargetRange - minTargetRange)) / (maxSourceRange - minSourceRange) + minTargetRange);
19916
- }
19917
-
19918
- const ELO = 'ELO';
19919
- const NTRP = 'NTRP';
19920
- const TRN = 'TRN';
19921
- const UTR = 'UTR';
19922
- const WTN = 'WTN';
19923
- const ratingConstants = {
19924
- ELO,
19925
- NTRP,
19926
- TRN,
19927
- UTR,
19928
- WTN,
19929
- };
19930
-
19931
- const ratingsParameters = {
19932
- [ELO]: {
19933
- defaultInitialization: 1500,
19934
- decimalsCount: 0,
19935
- range: [0, 3000],
19936
- ascending: true,
19937
- },
19938
- [NTRP]: {
19939
- accessors: ['ntrpRating', 'dntrpRatingHundredths'],
19940
- attributes: { ustaRatingType: '' },
19941
- accessor: 'dntrpRatingHundredths',
19942
- defaultInitialization: 3,
19943
- decimalsCount: 1,
19944
- ascending: true,
19945
- range: [1, 7],
19946
- },
19947
- [UTR]: {
19948
- defaultInitialization: 6,
19949
- accessors: ['utrRating'],
19950
- accessor: 'utrRating',
19951
- decimalsCount: 2,
19952
- ascending: true,
19953
- range: [1, 16],
19954
- },
19955
- [WTN]: {
19956
- attributes: { confidence: { generator: true, range: [60, 100] } },
19957
- accessors: ['wtnRating', 'confidence'],
19958
- defaultInitialization: 23,
19959
- accessor: 'wtnRating',
19960
- ascending: false,
19961
- decimalsCount: 2,
19962
- range: [40, 1],
19963
- },
19964
- };
19965
-
19966
- function getRatingConvertedToELO({ sourceRatingType, sourceRating }) {
19967
- const sourceRatingRange = ratingsParameters[sourceRatingType].range;
19968
- const invertedScale = sourceRatingRange[0] > sourceRatingRange[1];
19969
- const eloRatingRange = ratingsParameters[ELO].range;
19970
- return convertRange({
19971
- value: invertedScale ? sourceRatingRange[0] - sourceRating : sourceRating,
19972
- sourceRange: sourceRatingRange,
19973
- targetRange: eloRatingRange,
19974
- });
19975
- }
19976
- function getRatingConvertedFromELO({ targetRatingType, sourceRating }) {
19977
- const decimalPlaces = ratingsParameters[targetRatingType].decimalsCount || 0;
19978
- const targetRatingRange = ratingsParameters[targetRatingType].range;
19979
- const invertedScale = targetRatingRange[0] > targetRatingRange[1];
19980
- const maxTargetRatingRange = Math.max(...targetRatingRange);
19981
- const eloRatingRange = ratingsParameters[ELO].range;
19982
- const result = convertRange({
19983
- targetRange: targetRatingRange,
19984
- sourceRange: eloRatingRange,
19985
- value: sourceRating,
19986
- });
19987
- const convertedRating = parseFloat(result.toFixed(decimalPlaces));
19988
- return invertedScale ? maxTargetRatingRange - convertedRating : convertedRating;
19989
- }
19990
-
19991
- function getConvertedRating(params) {
19992
- const paramsCheck = checkRequiredParameters(params, [{ ratings: true, [OF_TYPE]: OBJECT }]);
19993
- if (paramsCheck.error)
19994
- return paramsCheck;
19995
- const matchUpType = params.matchUpType && [SINGLES, DOUBLES].includes(params.matchUpType) ? params.matchUpType : SINGLES;
19996
- const ratingTypes = Object.keys(ratingsParameters);
19997
- const targetRatingType = params.targetRatingType && ratingTypes.includes(params.targetRatingType) ? params.targetRatingType : ELO;
19998
- const sourceRatings = params.ratings[matchUpType]
19999
- ? params.ratings[matchUpType].reduce((sr, rating) => (sr.includes(rating.scaleName) ? sr : sr.concat(rating.scaleName)), [])
20000
- : [];
20001
- if (!sourceRatings)
20002
- return { error: NOT_FOUND };
20003
- const sourceRatingObject = params.ratings[matchUpType]?.find((rating) => rating.scaleName === targetRatingType) ??
20004
- params.ratings[matchUpType][0];
20005
- if (sourceRatings[0] === targetRatingType)
20006
- return sourceRatingObject;
20007
- const sourceRatingType = sourceRatingObject.scaleName;
20008
- const accessor = ratingsParameters[sourceRatingObject.scaleName].accessor;
20009
- const sourceRating = accessor ? sourceRatingObject.scaleValue[accessor] : sourceRatingObject.scaleValue;
20010
- const eloValue = getRatingConvertedToELO({ sourceRatingType, sourceRating });
20011
- const convertedRating = getRatingConvertedFromELO({
20012
- targetRatingType: targetRatingType,
20013
- sourceRating: eloValue,
20014
- });
20015
- return { convertedRating, sourceRating };
20016
- }
20017
-
20018
20060
  function getParticipantResults({ participantIds, pressureRating, matchUpFormat, tallyPolicy, perPlayer, matchUps, }) {
20019
20061
  const participantResults = {};
20020
20062
  const excludeMatchUpStatuses = tallyPolicy?.excludeMatchUpStatuses || [];
@@ -20134,6 +20176,7 @@ function getParticipantResults({ participantIds, pressureRating, matchUpFormat,
20134
20176
  processMatchUp({
20135
20177
  matchUpFormat: tieMatchUp.matchUpFormat,
20136
20178
  matchUpStatus: tieMatchUp.matchUpStatus,
20179
+ matchUpType: tieMatchUp.matchUpType,
20137
20180
  score: tieMatchUp.score,
20138
20181
  sides: tieMatchUp.sides,
20139
20182
  winningParticipantId,
@@ -20156,6 +20199,7 @@ function getParticipantResults({ participantIds, pressureRating, matchUpFormat,
20156
20199
  else {
20157
20200
  processMatchUp({
20158
20201
  matchUpFormat: matchUp.matchUpFormat ?? matchUpFormat,
20202
+ matchUpType: matchUp.matchUpType,
20159
20203
  isTieMatchUp: undefined,
20160
20204
  winningParticipantId,
20161
20205
  manualGamesOverride,
@@ -20269,24 +20313,11 @@ function processScore({ manualGamesOverride, participantResults, score, sides })
20269
20313
  }
20270
20314
  });
20271
20315
  }
20272
- 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, }) {
20273
20317
  const winningSideIndex = winningSide && winningSide - 1;
20274
20318
  const losingSideIndex = 1 - winningSideIndex;
20275
- if (pressureRating) {
20276
- const fixed2 = (value) => parseFloat(Number(Math.round(value * 1000) / 1000).toFixed(2));
20277
- const gamesWonSide1 = score?.sets?.reduce((total, set) => total + (set?.side1Score ?? 0), 0);
20278
- const gamesWonSide2 = score?.sets?.reduce((total, set) => total + (set.side2Score ?? 0), 0);
20279
- const side1 = sides.find(({ sideNumber }) => sideNumber === 1);
20280
- const side2 = sides.find(({ sideNumber }) => sideNumber === 2);
20281
- const { convertedRating: side1ConvertedRating } = getConvertedRating({ ratings: side1?.participant?.ratings });
20282
- const { convertedRating: side2ConvertedRating } = getConvertedRating({ ratings: side2?.participant?.ratings });
20283
- const side1Value = gamesWonSide1 * side2ConvertedRating;
20284
- const side2Value = gamesWonSide2 * side1ConvertedRating;
20285
- participantResults[side1?.participantId].pressureScores.push(fixed2(side1Value / (side1Value + side2Value)));
20286
- participantResults[side2?.participantId].pressureScores.push(fixed2(side2Value / (side1Value + side2Value)));
20287
- const highRange = Math.max(...ratingsParameters[ELO].range);
20288
- participantResults[side1?.participantId].ratingVariation.push(fixed2((side1ConvertedRating - side2ConvertedRating) / highRange));
20289
- participantResults[side2?.participantId].ratingVariation.push(fixed2((side2ConvertedRating - side1ConvertedRating) / highRange));
20319
+ if (pressureRating && matchUpType === SINGLES) {
20320
+ calculatePressureRatings({ participantResults, sides, score });
20290
20321
  }
20291
20322
  if (!isTieMatchUp) {
20292
20323
  processOutcome$1({
@@ -26542,9 +26573,9 @@ function calculateNewRatings(params) {
26542
26573
  const updatedWinnerRating = invertedScale
26543
26574
  ? ratingRange[0] - convertedUpdatedWinnerRating
26544
26575
  : convertedUpdatedWinnerRating;
26545
- let newWinnerRating = parseFloat(parseFloat(updatedWinnerRating).toFixed(decimalPlaces));
26576
+ let newWinnerRating = parseFloat(updatedWinnerRating.toFixed(decimalPlaces));
26546
26577
  const updatedLoserRating = invertedScale ? ratingRange[0] - convertedUpdatedLoserRating : convertedUpdatedLoserRating;
26547
- let newLoserRating = parseFloat(parseFloat(updatedLoserRating).toFixed(decimalPlaces));
26578
+ let newLoserRating = parseFloat(updatedLoserRating.toFixed(decimalPlaces));
26548
26579
  const percentageDifference = Math.max(...ratingRange)
26549
26580
  ? Math.abs(winnerRating - loserRating) / Math.max(...ratingRange)
26550
26581
  : 0;