2024-02-14 16:43:11 +00:00
< ng-container * ngIf = "this.isLoading" >
< div class = "main term" >
< div class = "text-center" >
Loading, please wait...
< / div >
< / div >
< / ng-container >
< ng-container * ngIf = "this.isError" >
< div class = "main term" >
< div class = "text-center" >
2025-05-10 09:46:11 +00:00
An error occurred. Maybe try again in a bit?
2024-02-14 16:43:11 +00:00
< / div >
< / div >
< / ng-container >
< ng-container * ngIf = "this.pair && !this.isLoading && !this.isError" >
< div class = "main term mb-2" >
< div class = "fade-stuff" >
< h1 class = "mb-4" > # viewing replay pair< / h1 >
< div class = "image-container" style = "margin: auto" >
< a href = "https://osu.ppy.sh/beatmaps/{{ this.pair.replays[0].beatmap_id }}?mode=osu" target = "_blank" >
< img ngSrc = "https://assets.ppy.sh/beatmaps/{{ this.pair.replays[0].beatmap_beatmapset_id }}/covers/cover.jpg" width = "260" height = "72"
alt="Beatmap Cover">
< div class = "overlay" >
< h4 >
{{ this.pair.replays[0].beatmap_title }} < span class = "text-muted" > by< / span > {{ this.pair.replays[0].beatmap_artist }}
< / h4 >
★{{ this.pair.replays[0].beatmap_star_rating | number: '1.0-2' }} {{ this.pair.replays[0].beatmap_version }}
< / div >
< / a >
< / div >
2024-11-05 20:26:51 +00:00
<!-- <div class="text - center mt - 2">
2024-03-05 12:32:08 +00:00
< a class = "btn" [ href ] = " ' https: / / replay . nise . moe / ' + this . pair . replays [ 0 ] . replay_id + ' / ' + this . pair . replays [ 1 ] . replay_id " target = "_blank" > Open in Replay Viewer< / a >
2024-11-05 20:26:51 +00:00
< / div > -->
2024-03-05 12:32:08 +00:00
2024-02-14 16:43:11 +00:00
< div class = "some-page-wrapper text-center" >
< div class = "row" >
< div class = "column" * ngFor = "let replay of this.pair.replays; let i = index" >
< div class = "blue-column" >
< h2 >
< a [ routerLink ] = " [ ' / s / ' + replay . replay_id ] " >
replay #{{ i + 1 }}
< / a >
< / h2 >
< a class = "btn" href = "https://osu.ppy.sh/scores/osu/{{ replay.replay_id }}" target = "_blank" > osu!web< / a >
< h1 >
{{ replay.score | number }}
< / h1 >
< div class = "badge-list" >
< span class = "badge" * ngFor = "let mod of replay.mods" >
{{ mod }}
< / span >
< / div >
< / div >
< / div >
< / div >
< / div >
< table class = "text-center mt-4" style = "width: 80%; margin: auto; margin-top: 40px" >
< tbody >
< tr >
< td > Player< / td >
< td >
2024-07-04 23:47:26 +00:00
< a [ routerLink ] = " [ ' / u / ' + this . pair . replays [ 0 ] . user_id ] " > {{ this.pair.replays[0].username }}< / a >
2024-02-14 16:43:11 +00:00
< a class = "btn" style = "margin-left: 5px" href = "https://osu.ppy.sh/users/{{ this.pair.replays[0].user_id }}" target = "_blank" > osu!web< / a >
< / td >
< td >
2024-07-04 23:47:26 +00:00
< a [ routerLink ] = " [ ' / u / ' + this . pair . replays [ 1 ] . user_id ] " > {{ this.pair.replays[1].username }}< / a >
2024-02-14 16:43:11 +00:00
< a class = "btn" style = "margin-left: 5px" href = "https://osu.ppy.sh/users/{{ this.pair.replays[1].user_id }}" target = "_blank" > osu!web< / a >
< / td >
< / tr >
< tr >
< td > Date< / td >
< td > {{ this.pair.replays[0].date }}< / td >
< td > {{ this.pair.replays[1].date }}< / td >
< / tr >
< tr >
< td > PP< / td >
< td > {{ this.pair.replays[0].pp | number: '1.2-2' }}< / td >
< td > {{ this.pair.replays[1].pp | number: '1.2-2' }}< / td >
< / tr >
< tr >
< td > Max Combo< / td >
< td > {{ this.pair.replays[0].max_combo }}x < span * ngIf = "this.pair.replays[0].perfect" class = "badge badge-green" > perfect< / span > < / td >
< td > {{ this.pair.replays[1].max_combo }}x < span * ngIf = "this.pair.replays[1].perfect" class = "badge badge-green" > perfect< / span > < / td >
< / tr >
< tr >
< td > Accuracy< / td >
< td > {{ calculateAccuracy(this.pair.replays[0]) | number: '1.2-2' }}%< / td >
< td > {{ calculateAccuracy(this.pair.replays[1]) | number: '1.2-2' }}%< / td >
< / tr >
< tr >
< td > 300x< / td >
< td > {{ this.pair.replays[0].count_300 }}< / td >
< td > {{ this.pair.replays[1].count_300 }}< / td >
< / tr >
< tr >
< td > 100x< / td >
< td > {{ this.pair.replays[0].count_100 }}< / td >
< td > {{ this.pair.replays[1].count_100 }}< / td >
< / tr >
< tr >
< td > 50x< / td >
< td > {{ this.pair.replays[0].count_50 }}< / td >
< td > {{ this.pair.replays[1].count_50 }}< / td >
< / tr >
< tr >
< td > Misses< / td >
< td > {{ this.pair.replays[0].count_miss }}< / td >
< td > {{ this.pair.replays[1].count_miss }}< / td >
< / tr >
< tr >
< td > Grade< / td >
< td > < app-osu-grade [ grade ] = " this . pair . replays [ 0 ] . rank " > < / app-osu-grade > < / td >
< td > < app-osu-grade [ grade ] = " this . pair . replays [ 1 ] . rank " > < / app-osu-grade > < / td >
< / tr >
< / tbody >
< / table >
< / div >
< / div >
< div class = "main term mb-2" >
< div class = "fade-stuff" >
< h1 class = "mb-4" > # analysis< / h1 >
< div class = "text-center mb-4 flex-container" >
< div >
< h2 > Similarity< / h2 >
< div style = "font-size: 24px" > {{ this.pair.statistics.similarity | number: '1.2-3' }}< / div >
< p > this number can be understood as the average difference between the two replays in pixels.< / p >
< p > two copies of the same replay would score < strong > 0< / strong > , so lower values means < strong > more< / strong > similarity.< / p >
< p > a common lower bound for replay stealing would *usually* be around < strong > 10 - 15< / strong > < / p >
< / div >
< div >
< h2 > Correlation< / h2 >
< div style = "font-size: 24px" > {{ this.pair.statistics.correlation | number: '1.2-4' }}< / div >
< p > this number (range: [0, 1]) also takes into account time-shifts and other variables< / p >
< p > two copies of the same replay would score < strong > 1< / strong > , so values closer to < strong > 1< / strong > mean more similarity and lower values closer to < strong > 0< / strong > mean less.< / p >
< p > a common upper bound for replay stealing would be *usually* above < strong > 0.997< / strong > < / p >
< / div >
< / div >
< / div >
< / div >
< / ng-container >