@rian8337/osu-droid-replay-analyzer 4.0.0-beta.37 → 4.0.0-beta.39

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.js CHANGED
@@ -294,9 +294,6 @@ exports.HitResult = void 0;
294
294
  * Utility to check whether or not a beatmap is three-fingered for rebalance scores.
295
295
  */
296
296
  class RebalanceThreeFingerChecker {
297
- get hitWindow50() {
298
- return this.hitWindow.hitWindowFor50(this.isPrecise);
299
- }
300
297
  /**
301
298
  * @param beatmap The beatmap to analyze.
302
299
  * @param data The data of the replay.
@@ -327,9 +324,10 @@ class RebalanceThreeFingerChecker {
327
324
  this.beatmap = beatmap;
328
325
  this.data = data;
329
326
  this.difficultyAttributes = difficultyAttributes;
330
- this.isPrecise = difficultyAttributes.mods.some((m) => m instanceof osuBase.ModPrecise);
331
327
  this.isHardRock = difficultyAttributes.mods.some((m) => m instanceof osuBase.ModHardRock);
332
- this.hitWindow = new osuBase.DroidHitWindow(beatmap.difficulty.od);
328
+ this.hitWindow = difficultyAttributes.mods.some((m) => m instanceof osuBase.ModPrecise)
329
+ ? new osuBase.PreciseDroidHitWindow(beatmap.difficulty.od)
330
+ : new osuBase.DroidHitWindow(beatmap.difficulty.od);
333
331
  }
334
332
  /**
335
333
  * Checks whether a beatmap is eligible to be detected for 3-finger.
@@ -383,7 +381,7 @@ class RebalanceThreeFingerChecker {
383
381
  timeBefore += objectBeforeData.accuracy;
384
382
  }
385
383
  else {
386
- timeBefore += this.hitWindow.hitWindowFor50(this.isPrecise);
384
+ timeBefore += this.hitWindow.mehWindow;
387
385
  }
388
386
  }
389
387
  const afterIndex = beforeIndex + 1;
@@ -413,31 +411,31 @@ class RebalanceThreeFingerChecker {
413
411
  const firstObject = objects[0];
414
412
  const lastObject = objects.at(-1);
415
413
  // For sliders, automatically set hit window length to be as lenient as possible.
416
- let firstObjectHitWindow = this.hitWindow.hitWindowFor50(this.isPrecise);
414
+ let firstObjectHitWindow = this.hitWindow.mehWindow;
417
415
  if (firstObject instanceof osuBase.Circle) {
418
416
  switch (firstObjectResult) {
419
417
  case exports.HitResult.great:
420
- firstObjectHitWindow = this.hitWindow.hitWindowFor300(this.isPrecise);
418
+ firstObjectHitWindow = this.hitWindow.greatWindow;
421
419
  break;
422
420
  case exports.HitResult.good:
423
- firstObjectHitWindow = this.hitWindow.hitWindowFor100(this.isPrecise);
421
+ firstObjectHitWindow = this.hitWindow.okWindow;
424
422
  break;
425
423
  default:
426
- firstObjectHitWindow = this.hitWindow.hitWindowFor50(this.isPrecise);
424
+ firstObjectHitWindow = this.hitWindow.mehWindow;
427
425
  }
428
426
  }
429
427
  // For sliders, automatically set hit window length to be as lenient as possible.
430
- let lastObjectHitWindow = this.hitWindow.hitWindowFor50(this.isPrecise);
428
+ let lastObjectHitWindow = this.hitWindow.mehWindow;
431
429
  if (lastObject instanceof osuBase.Circle) {
432
430
  switch (lastObjectResult) {
433
431
  case exports.HitResult.great:
434
- lastObjectHitWindow = this.hitWindow.hitWindowFor300(this.isPrecise);
432
+ lastObjectHitWindow = this.hitWindow.greatWindow;
435
433
  break;
436
434
  case exports.HitResult.good:
437
- lastObjectHitWindow = this.hitWindow.hitWindowFor100(this.isPrecise);
435
+ lastObjectHitWindow = this.hitWindow.okWindow;
438
436
  break;
439
437
  default:
440
- lastObjectHitWindow = this.hitWindow.hitWindowFor50(this.isPrecise);
438
+ lastObjectHitWindow = this.hitWindow.mehWindow;
441
439
  }
442
440
  }
443
441
  else if (lastObject instanceof osuBase.Slider) {
@@ -507,7 +505,9 @@ class RebalanceThreeFingerChecker {
507
505
  }
508
506
  // Check for sliderbreaks and treat them as misses.
509
507
  if (object instanceof osuBase.Slider &&
510
- objectData.accuracy === Math.floor(this.hitWindow50) + 13) {
508
+ (-this.hitWindow.mehWindow > objectData.accuracy ||
509
+ objectData.accuracy >
510
+ Math.min(this.hitWindow.mehWindow, object.duration))) {
511
511
  return -1;
512
512
  }
513
513
  const hitTime = object.startTime + objectData.accuracy;
@@ -593,7 +593,9 @@ class RebalanceThreeFingerChecker {
593
593
  }
594
594
  // Check for sliderbreaks and treat them as misses.
595
595
  if (object instanceof osuBase.Slider &&
596
- objectData.accuracy === Math.floor(this.hitWindow50) + 13) {
596
+ (-this.hitWindow.mehWindow > objectData.accuracy ||
597
+ objectData.accuracy >
598
+ Math.min(this.hitWindow.mehWindow, object.duration))) {
597
599
  return -1;
598
600
  }
599
601
  const hitTime = object.startTime + objectData.accuracy;
@@ -761,9 +763,6 @@ class ReplayData {
761
763
  * Utility to check whether or not a beatmap is three-fingered for rebalance scores.
762
764
  */
763
765
  class ThreeFingerChecker {
764
- get hitWindow50() {
765
- return this.hitWindow.hitWindowFor50(this.isPrecise);
766
- }
767
766
  /**
768
767
  * @param beatmap The beatmap to analyze.
769
768
  * @param data The data of the replay.
@@ -794,9 +793,10 @@ class ThreeFingerChecker {
794
793
  this.beatmap = beatmap;
795
794
  this.data = data;
796
795
  this.difficultyAttributes = difficultyAttributes;
797
- this.isPrecise = difficultyAttributes.mods.some((m) => m instanceof osuBase.ModPrecise);
798
796
  this.isHardRock = difficultyAttributes.mods.some((m) => m instanceof osuBase.ModHardRock);
799
- this.hitWindow = new osuBase.DroidHitWindow(beatmap.difficulty.od);
797
+ this.hitWindow = difficultyAttributes.mods.some((m) => m instanceof osuBase.ModPrecise)
798
+ ? new osuBase.PreciseDroidHitWindow(beatmap.difficulty.od)
799
+ : new osuBase.DroidHitWindow(beatmap.difficulty.od);
800
800
  }
801
801
  /**
802
802
  * Checks whether a beatmap is eligible to be detected for 3-finger.
@@ -850,7 +850,7 @@ class ThreeFingerChecker {
850
850
  timeBefore += objectBeforeData.accuracy;
851
851
  }
852
852
  else {
853
- timeBefore += this.hitWindow.hitWindowFor50(this.isPrecise);
853
+ timeBefore += this.hitWindow.mehWindow;
854
854
  }
855
855
  }
856
856
  const afterIndex = beforeIndex + 1;
@@ -880,31 +880,31 @@ class ThreeFingerChecker {
880
880
  const firstObject = objects[0];
881
881
  const lastObject = objects.at(-1);
882
882
  // For sliders, automatically set hit window length to be as lenient as possible.
883
- let firstObjectHitWindow = this.hitWindow.hitWindowFor50(this.isPrecise);
883
+ let firstObjectHitWindow = this.hitWindow.mehWindow;
884
884
  if (firstObject instanceof osuBase.Circle) {
885
885
  switch (firstObjectResult) {
886
886
  case exports.HitResult.great:
887
- firstObjectHitWindow = this.hitWindow.hitWindowFor300(this.isPrecise);
887
+ firstObjectHitWindow = this.hitWindow.greatWindow;
888
888
  break;
889
889
  case exports.HitResult.good:
890
- firstObjectHitWindow = this.hitWindow.hitWindowFor100(this.isPrecise);
890
+ firstObjectHitWindow = this.hitWindow.okWindow;
891
891
  break;
892
892
  default:
893
- firstObjectHitWindow = this.hitWindow.hitWindowFor50(this.isPrecise);
893
+ firstObjectHitWindow = this.hitWindow.mehWindow;
894
894
  }
895
895
  }
896
896
  // For sliders, automatically set hit window length to be as lenient as possible.
897
- let lastObjectHitWindow = this.hitWindow.hitWindowFor50(this.isPrecise);
897
+ let lastObjectHitWindow = this.hitWindow.mehWindow;
898
898
  if (lastObject instanceof osuBase.Circle) {
899
899
  switch (lastObjectResult) {
900
900
  case exports.HitResult.great:
901
- lastObjectHitWindow = this.hitWindow.hitWindowFor300(this.isPrecise);
901
+ lastObjectHitWindow = this.hitWindow.greatWindow;
902
902
  break;
903
903
  case exports.HitResult.good:
904
- lastObjectHitWindow = this.hitWindow.hitWindowFor100(this.isPrecise);
904
+ lastObjectHitWindow = this.hitWindow.okWindow;
905
905
  break;
906
906
  default:
907
- lastObjectHitWindow = this.hitWindow.hitWindowFor50(this.isPrecise);
907
+ lastObjectHitWindow = this.hitWindow.mehWindow;
908
908
  }
909
909
  }
910
910
  else if (lastObject instanceof osuBase.Slider) {
@@ -974,7 +974,9 @@ class ThreeFingerChecker {
974
974
  }
975
975
  // Check for sliderbreaks and treat them as misses.
976
976
  if (object instanceof osuBase.Slider &&
977
- objectData.accuracy === Math.floor(this.hitWindow50) + 13) {
977
+ (-this.hitWindow.mehWindow > objectData.accuracy ||
978
+ objectData.accuracy >
979
+ Math.min(this.hitWindow.mehWindow, object.duration))) {
978
980
  return -1;
979
981
  }
980
982
  const hitTime = object.startTime + objectData.accuracy;
@@ -1060,7 +1062,9 @@ class ThreeFingerChecker {
1060
1062
  }
1061
1063
  // Check for sliderbreaks and treat them as misses.
1062
1064
  if (object instanceof osuBase.Slider &&
1063
- objectData.accuracy === Math.floor(this.hitWindow50) + 13) {
1065
+ (-this.hitWindow.mehWindow > objectData.accuracy ||
1066
+ objectData.accuracy >
1067
+ Math.min(this.hitWindow.mehWindow, object.duration))) {
1064
1068
  return -1;
1065
1069
  }
1066
1070
  const hitTime = object.startTime + objectData.accuracy;
@@ -1195,10 +1199,11 @@ class TwoHandChecker {
1195
1199
  this.indexedHitObjects = [];
1196
1200
  this.calculator = calculator;
1197
1201
  this.data = data;
1198
- const greatWindow = new osuBase.OsuHitWindow(calculator.attributes.overallDifficulty).hitWindowFor300() * calculator.attributes.clockRate;
1199
- const isPrecise = calculator.mods.some((m) => m instanceof osuBase.ModPrecise);
1200
- this.hitWindow = new osuBase.DroidHitWindow(osuBase.DroidHitWindow.hitWindow300ToOD(greatWindow, isPrecise));
1201
- this.hitWindow50 = this.hitWindow.hitWindowFor50(calculator.mods.some((m) => m instanceof osuBase.ModPrecise));
1202
+ const greatWindow = new osuBase.OsuHitWindow(calculator.attributes.overallDifficulty)
1203
+ .greatWindow * calculator.attributes.clockRate;
1204
+ this.hitWindow = calculator.mods.some((m) => m instanceof osuBase.ModPrecise)
1205
+ ? new osuBase.PreciseDroidHitWindow(osuBase.PreciseDroidHitWindow.greatWindowToOD(greatWindow))
1206
+ : new osuBase.DroidHitWindow(osuBase.DroidHitWindow.greatWindowToOD(greatWindow));
1202
1207
  this.isHardRock = calculator.mods.some((m) => m instanceof osuBase.ModHardRock);
1203
1208
  // this.csvString = `Mods,${
1204
1209
  // data.convertedMods.reduce((a, m) => a + m.acronym, "") || "NM"
@@ -1513,16 +1518,15 @@ class TwoHandChecker {
1513
1518
  cursorTime: object.startTime,
1514
1519
  };
1515
1520
  }
1516
- let hitWindow = this.hitWindow50;
1517
- const isPrecise = this.calculator.mods.some((m) => m instanceof osuBase.ModPrecise);
1521
+ let hitWindow = this.hitWindow.mehWindow;
1518
1522
  // For sliders, set the hit window to as lenient as possible.
1519
1523
  if (object instanceof osuBase.Circle) {
1520
1524
  switch (data.result) {
1521
1525
  case exports.HitResult.great:
1522
- hitWindow = this.hitWindow.hitWindowFor300(isPrecise);
1526
+ hitWindow = this.hitWindow.greatWindow;
1523
1527
  break;
1524
1528
  case exports.HitResult.good:
1525
- hitWindow = this.hitWindow.hitWindowFor100(isPrecise);
1529
+ hitWindow = this.hitWindow.okWindow;
1526
1530
  break;
1527
1531
  }
1528
1532
  }
@@ -1793,7 +1797,9 @@ class SliderCheeseChecker {
1793
1797
  this.beatmap = beatmap;
1794
1798
  this.data = data;
1795
1799
  this.difficultyAttributes = difficultyAttributes;
1796
- this.hitWindow50 = new osuBase.DroidHitWindow(beatmap.difficulty.od).hitWindowFor50(difficultyAttributes.mods.some((m) => m instanceof osuBase.ModPrecise));
1800
+ this.hitWindow50 = difficultyAttributes.mods.some((m) => m instanceof osuBase.ModPrecise)
1801
+ ? new osuBase.PreciseDroidHitWindow(beatmap.difficulty.od).mehWindow
1802
+ : new osuBase.DroidHitWindow(beatmap.difficulty.od).mehWindow;
1797
1803
  this.isHardRock = difficultyAttributes.mods.some((m) => m instanceof osuBase.ModHardRock);
1798
1804
  }
1799
1805
  /**
@@ -1829,13 +1835,15 @@ class SliderCheeseChecker {
1829
1835
  if (difficultSlider.index >= this.data.hitObjectData.length) {
1830
1836
  continue;
1831
1837
  }
1838
+ const object = objects[difficultSlider.index];
1832
1839
  const objectData = this.data.hitObjectData[difficultSlider.index];
1833
1840
  // If a miss or slider break occurs, we disregard the check for that slider.
1834
1841
  if (objectData.result === exports.HitResult.miss ||
1835
- objectData.accuracy === Math.floor(this.hitWindow50) + 13) {
1842
+ -this.hitWindow50 > objectData.accuracy ||
1843
+ objectData.accuracy >
1844
+ Math.min(this.hitWindow50, object.duration)) {
1836
1845
  continue;
1837
1846
  }
1838
- const object = objects[difficultSlider.index];
1839
1847
  const objectStartPosition = object.getStackedPosition(osuBase.Modes.droid);
1840
1848
  // These time boundaries should consider the delta time between the previous and next
1841
1849
  // object as well as their hit accuracy. However, they are somewhat complicated to
@@ -2005,6 +2013,20 @@ class SliderCheeseChecker {
2005
2013
  * This is used when analyzing replays using replay analyzer.
2006
2014
  */
2007
2015
  class ReplayV3Data extends ReplayData {
2016
+ /**
2017
+ * The complete mod string of this replay (mods, speed multiplier, and forced difficulty statistics combined).
2018
+ */
2019
+ get completeModString() {
2020
+ return this.modString;
2021
+ }
2022
+ /**
2023
+ * The mod string of this replay (mods only).
2024
+ */
2025
+ get modString() {
2026
+ return this.convertedMods.length > 0
2027
+ ? this.convertedMods.map((v) => v.acronym).join("")
2028
+ : "No Mod";
2029
+ }
2008
2030
  constructor(values) {
2009
2031
  super(values);
2010
2032
  this.time = values.time;
@@ -2025,6 +2047,23 @@ class ReplayV3Data extends ReplayData {
2025
2047
  * This is used when analyzing replays using replay analyzer.
2026
2048
  */
2027
2049
  class ReplayV4Data extends ReplayV3Data {
2050
+ get completeModString() {
2051
+ let finalString = this.modString;
2052
+ const customStats = [];
2053
+ if (this.speedMultiplier !== 1) {
2054
+ customStats.push(`${this.speedMultiplier}x`);
2055
+ }
2056
+ if (this.forceAR !== undefined) {
2057
+ customStats.push(`AR${this.forceAR}`);
2058
+ }
2059
+ if (this.flashlightFollowDelay !== undefined) {
2060
+ customStats.push(`FLD${this.flashlightFollowDelay}`);
2061
+ }
2062
+ if (customStats.length > 0) {
2063
+ finalString += ` (${customStats.join(", ")})`;
2064
+ }
2065
+ return finalString;
2066
+ }
2028
2067
  constructor(values) {
2029
2068
  var _a, _b;
2030
2069
  super(values);
@@ -2042,6 +2081,32 @@ class ReplayV4Data extends ReplayV3Data {
2042
2081
  * This is used when analyzing replays using replay analyzer.
2043
2082
  */
2044
2083
  class ReplayV5Data extends ReplayV4Data {
2084
+ get completeModString() {
2085
+ let finalString = this.modString;
2086
+ const customStats = [];
2087
+ if (this.speedMultiplier !== 1) {
2088
+ customStats.push(`${this.speedMultiplier}x`);
2089
+ }
2090
+ if (this.forceAR !== undefined) {
2091
+ customStats.push(`AR${this.forceAR}`);
2092
+ }
2093
+ if (this.forceOD !== undefined) {
2094
+ customStats.push(`OD${this.forceOD}`);
2095
+ }
2096
+ if (this.forceCS !== undefined) {
2097
+ customStats.push(`CS${this.forceCS}`);
2098
+ }
2099
+ if (this.forceHP !== undefined) {
2100
+ customStats.push(`HP${this.forceHP}`);
2101
+ }
2102
+ if (this.flashlightFollowDelay !== undefined) {
2103
+ customStats.push(`FLD${this.flashlightFollowDelay}`);
2104
+ }
2105
+ if (customStats.length > 0) {
2106
+ finalString += ` (${customStats.join(", ")})`;
2107
+ }
2108
+ return finalString;
2109
+ }
2045
2110
  constructor(values) {
2046
2111
  super(values);
2047
2112
  this.forceCS = values.forceCS;
@@ -2157,12 +2222,9 @@ class ReplayAnalyzer {
2157
2222
  : (_b = (_a = this.difficultyAttributes) === null || _a === void 0 ? void 0 : _a.mods.filter((m) => m.isApplicableToDroid())) !== null && _b !== void 0 ? _b : [];
2158
2223
  const adjustedDifficulty = new osuBase.BeatmapDifficulty(beatmap.difficulty);
2159
2224
  osuBase.ModUtil.applyModsToBeatmapDifficulty(adjustedDifficulty, osuBase.Modes.droid, mods, this.data.isReplayV4() ? this.data.speedMultiplier : 1);
2160
- const hitWindow50 = new osuBase.DroidHitWindow(adjustedDifficulty.od).hitWindowFor50(mods.some((m) => m instanceof osuBase.ModPrecise));
2161
- // The accuracy of sliders is set to (50 hit window)ms + 13ms if their head was not hit:
2162
- // https://github.com/osudroid/osu-droid/blob/6306c68e3ffaf671eac794bf45cc95c0f3313a82/src/ru/nsu/ccfit/zuev/osu/game/Slider.java#L821
2163
- //
2164
- // In such cases, the slider is skipped.
2165
- const sliderbreakHitOffset = Math.floor(hitWindow50) + 13;
2225
+ const mehWindow = mods.some((m) => m instanceof osuBase.ModPrecise)
2226
+ ? new osuBase.PreciseDroidHitWindow(adjustedDifficulty.od).mehWindow
2227
+ : new osuBase.DroidHitWindow(adjustedDifficulty.od).mehWindow;
2166
2228
  const accuracies = [];
2167
2229
  for (let i = 0; i < hitObjectData.length; ++i) {
2168
2230
  const v = hitObjectData[i];
@@ -2172,7 +2234,10 @@ class ReplayAnalyzer {
2172
2234
  continue;
2173
2235
  }
2174
2236
  const { accuracy } = v;
2175
- if (o instanceof osuBase.Slider && accuracy === sliderbreakHitOffset) {
2237
+ if (o instanceof osuBase.Slider &&
2238
+ // Do not include slider breaks.
2239
+ (-mehWindow > accuracy ||
2240
+ accuracy > Math.min(mehWindow, o.duration))) {
2176
2241
  accuracies.push(0);
2177
2242
  continue;
2178
2243
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rian8337/osu-droid-replay-analyzer",
3
- "version": "4.0.0-beta.37",
3
+ "version": "4.0.0-beta.39",
4
4
  "description": "A replay analyzer for analyzing osu!droid replay files.",
5
5
  "keywords": [
6
6
  "osu",
@@ -34,9 +34,9 @@
34
34
  "url": "https://github.com/Rian8337/osu-droid-module/issues"
35
35
  },
36
36
  "dependencies": {
37
- "@rian8337/osu-base": "^4.0.0-beta.31",
38
- "@rian8337/osu-difficulty-calculator": "^4.0.0-beta.32",
39
- "@rian8337/osu-rebalance-difficulty-calculator": "^4.0.0-beta.32",
37
+ "@rian8337/osu-base": "^4.0.0-beta.39",
38
+ "@rian8337/osu-difficulty-calculator": "^4.0.0-beta.39",
39
+ "@rian8337/osu-rebalance-difficulty-calculator": "^4.0.0-beta.39",
40
40
  "java-deserialization": "^0.1.0",
41
41
  "unzipper": "^0.10.11"
42
42
  },
@@ -46,5 +46,5 @@
46
46
  "publishConfig": {
47
47
  "access": "public"
48
48
  },
49
- "gitHead": "6b7f7e7470ac9622d9b1ea5f74a7cd517671f114"
49
+ "gitHead": "6039ff691d968464d4b111e0b5a88775fb055281"
50
50
  }
@@ -1,4 +1,4 @@
1
- import { Vector2, Accuracy, Mod, IModApplicableToDroid, Beatmap } from '@rian8337/osu-base';
1
+ import { Vector2, Accuracy, ScoreRank, Mod, IModApplicableToDroid, Beatmap } from '@rian8337/osu-base';
2
2
  import { ExtendedDroidDifficultyAttributes, DroidDifficultyCalculator as DroidDifficultyCalculator$1 } from '@rian8337/osu-rebalance-difficulty-calculator';
3
3
  import { ExtendedDroidDifficultyAttributes as ExtendedDroidDifficultyAttributes$1, DroidDifficultyCalculator } from '@rian8337/osu-difficulty-calculator';
4
4
 
@@ -346,11 +346,6 @@ interface ExportedReplayJSONV2 {
346
346
  replaydata: ExportedReplayJSONDataV2;
347
347
  }
348
348
 
349
- /**
350
- * Represents the grade of a score.
351
- */
352
- type Grade = "XH" | "X" | "SH" | "S" | "A" | "B" | "C" | "D";
353
-
354
349
  /**
355
350
  * The result of a hit in an osu!droid replay.
356
351
  */
@@ -511,7 +506,7 @@ interface ReplayInformation {
511
506
  /**
512
507
  * The achieved rank in the play.
513
508
  */
514
- rank: Grade;
509
+ rank: ScoreRank;
515
510
  /**
516
511
  * Enabled modifications during the play that have been converted to their respective `Mod` instances.
517
512
  *
@@ -600,6 +595,14 @@ declare class ReplayV3Data extends ReplayData {
600
595
  * Enabled modifications during the play that have been converted to their respective `Mod` instances.
601
596
  */
602
597
  readonly convertedMods: (Mod & IModApplicableToDroid)[];
598
+ /**
599
+ * The complete mod string of this replay (mods, speed multiplier, and forced difficulty statistics combined).
600
+ */
601
+ get completeModString(): string;
602
+ /**
603
+ * The mod string of this replay (mods only).
604
+ */
605
+ protected get modString(): string;
603
606
  constructor(values: ReplayInformation);
604
607
  }
605
608
 
@@ -623,6 +626,7 @@ declare class ReplayV4Data extends ReplayV3Data {
623
626
  * The follow delay set for the FL mod, in seconds.
624
627
  */
625
628
  readonly flashlightFollowDelay: number;
629
+ get completeModString(): string;
626
630
  constructor(values: ReplayInformation);
627
631
  }
628
632
 
@@ -646,6 +650,7 @@ declare class ReplayV5Data extends ReplayV4Data {
646
650
  * The force HP of the replay.
647
651
  */
648
652
  readonly forceHP?: number;
653
+ get completeModString(): string;
649
654
  constructor(values: ReplayInformation);
650
655
  }
651
656
 
@@ -680,7 +685,7 @@ declare class ReplayData {
680
685
  /**
681
686
  * The achieved rank in the play.
682
687
  */
683
- readonly rank: Grade;
688
+ readonly rank: ScoreRank;
684
689
  /**
685
690
  * The amount of geki and 300 katu achieved in the play. See {@link https://osu.ppy.sh/help/wiki/Score this}
686
691
  * osu! wiki page for more information.
@@ -777,9 +782,7 @@ declare class RebalanceThreeFingerChecker {
777
782
  * Nerf factors from all sections that were three-fingered.
778
783
  */
779
784
  private readonly nerfFactors;
780
- private readonly isPrecise;
781
785
  private readonly isHardRock;
782
- private get hitWindow50();
783
786
  /**
784
787
  * @param beatmap The beatmap to analyze.
785
788
  * @param data The data of the replay.
@@ -1104,9 +1107,7 @@ declare class ThreeFingerChecker {
1104
1107
  * Nerf factors from all sections that were three-fingered.
1105
1108
  */
1106
1109
  private readonly nerfFactors;
1107
- private readonly isPrecise;
1108
1110
  private readonly isHardRock;
1109
- private get hitWindow50();
1110
1111
  /**
1111
1112
  * @param beatmap The beatmap to analyze.
1112
1113
  * @param data The data of the replay.
@@ -1213,10 +1214,6 @@ declare class TwoHandChecker {
1213
1214
  * The osu!droid hitwindow of the analyzed beatmap.
1214
1215
  */
1215
1216
  private readonly hitWindow;
1216
- /**
1217
- * The 50 osu!droid hit window of the analyzed beatmap.
1218
- */
1219
- private readonly hitWindow50;
1220
1217
  private readonly isHardRock;
1221
1218
  /**
1222
1219
  * @param calculator The difficulty calculator to analyze.
@@ -1265,4 +1262,4 @@ declare class TwoHandChecker {
1265
1262
  private getCursorPosition;
1266
1263
  }
1267
1264
 
1268
- export { CursorData, type CursorInformation, CursorOccurrence, CursorOccurrenceGroup, type ExportedReplayJSONDataV1, type ExportedReplayJSONDataV2, type ExportedReplayJSONV1, type ExportedReplayJSONV2, type Grade, type HitErrorInformation, HitResult, MovementType, RebalanceThreeFingerChecker, ReplayAnalyzer, ReplayData, ReplayObjectData, ReplayV3Data, ReplayV4Data, ReplayV5Data, SliderCheeseChecker, type SliderCheeseInformation, ThreeFingerChecker, type ThreeFingerInformation, TwoHandChecker, type TwoHandInformation };
1265
+ export { CursorData, type CursorInformation, CursorOccurrence, CursorOccurrenceGroup, type ExportedReplayJSONDataV1, type ExportedReplayJSONDataV2, type ExportedReplayJSONV1, type ExportedReplayJSONV2, type HitErrorInformation, HitResult, MovementType, RebalanceThreeFingerChecker, ReplayAnalyzer, ReplayData, ReplayObjectData, ReplayV3Data, ReplayV4Data, ReplayV5Data, SliderCheeseChecker, type SliderCheeseInformation, ThreeFingerChecker, type ThreeFingerInformation, TwoHandChecker, type TwoHandInformation };