From f18c2dee3bbd03f761a06494e93f9bb2f2367755 Mon Sep 17 00:00:00 2001 From: Taken Date: Tue, 2 Sep 2025 00:07:36 +0200 Subject: [PATCH] Added first table row --- .../player/[ign]/_stats/duels/duels.tsx | 4 +- .../player/[ign]/_stats/duels/table.tsx | 24 +- src/lib/hypixel/duels/duels.ts | 56 ++- src/lib/schema/stats.ts | 417 ++++++++---------- 4 files changed, 250 insertions(+), 251 deletions(-) diff --git a/src/app/(stats)/player/[ign]/_stats/duels/duels.tsx b/src/app/(stats)/player/[ign]/_stats/duels/duels.tsx index aa78873..c1c4d0b 100644 --- a/src/app/(stats)/player/[ign]/_stats/duels/duels.tsx +++ b/src/app/(stats)/player/[ign]/_stats/duels/duels.tsx @@ -2,7 +2,7 @@ import { AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ import { Card, CardContent } from "@/components/ui/card" import { Separator } from "@/components/ui/separator" import { formatNumber } from "@/lib/formatters" -import { getDivision, getMostPlayed } from "@/lib/hypixel/duels/duels" +import { getAllDivisions, getMostPlayed } from "@/lib/hypixel/duels/duels" import { romanize } from "@/lib/hypixel/general" import { NonNullStats } from "@/lib/schema/player" import CollapsedStats from "../../_components/CollapsedStats" @@ -14,7 +14,7 @@ export default function DuelsStats({ stats }: { stats: NonNullStats["Duels"] }) const wl = stats.wins / stats.losses const kd = stats.kills / stats.deaths - const div = getDivision("all_modes", stats) + const div = getAllDivisions(stats) const mostPlayed = getMostPlayed(stats) return ( diff --git a/src/app/(stats)/player/[ign]/_stats/duels/table.tsx b/src/app/(stats)/player/[ign]/_stats/duels/table.tsx index bd003ee..8d5639f 100644 --- a/src/app/(stats)/player/[ign]/_stats/duels/table.tsx +++ b/src/app/(stats)/player/[ign]/_stats/duels/table.tsx @@ -1,10 +1,15 @@ -import { Table, TableHead, TableHeader, TableRow } from "@/components/ui/table" +import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table" +import { formatNumber } from "@/lib/formatters" +import { getDuelsModeStats, getModeTitle } from "@/lib/hypixel/duels/duels" import { NonNullStats } from "@/lib/schema/player" export default function DuelsStatTable({ stats }: { stats: NonNullStats["Duels"] }) { return ( + + +
) } @@ -36,3 +41,20 @@ function DuelsTableHeader() { ) } + +function UHC1v1Stats({ stats }: { stats: NonNullStats["Duels"] }) { + if (!stats) return null + + const modeStats = getDuelsModeStats("uhc_duel", stats) + const title = getModeTitle("uhc_duel") + + return ( + + {title} + I + {modeStats.map((v, i) => { + return {typeof v === "number" ? formatNumber(v) : v} + })} + + ) +} diff --git a/src/lib/hypixel/duels/duels.ts b/src/lib/hypixel/duels/duels.ts index e9db055..2e0c023 100644 --- a/src/lib/hypixel/duels/duels.ts +++ b/src/lib/hypixel/duels/duels.ts @@ -1,16 +1,23 @@ import { DIVISIONS, MODES } from "@/data/hypixel/duels" +import { formatNumber } from "@/lib/formatters" import { NonNullStats } from "@/lib/schema/player" +import { devide } from "../general" -type DuelType = "all_modes" export type Div = { name: typeof DIVISIONS[number]["name"] level: number color: typeof DIVISIONS[number]["color"] } -export function getDivision(duelType: DuelType, stats: NonNullable) { +export function getModeTitle(id: typeof MODES[number]["id"]) { + const div = MODES.find(d => d.id === id) + + return div!.name +} + +export function getAllDivisions(stats: NonNullable) { for (const div of DIVISIONS.slice().reverse()) { - const index = `${duelType}_${div.id}_title_prestige` as const + const index = `all_modes_${div.id}_title_prestige` as const const val = stats[index] if (val > 0) { return { @@ -36,3 +43,46 @@ export function getMostPlayed(stats: NonNullable) { } return mostPlayed } + +type Mode = typeof MODES[number]["id"] + +// export function getBestMode(stats: NonNullable) { +// const { wins_bedwars: solo } = getBedwarsModeStats("solo", stats, true) +// const { wins_bedwars: doubles } = getBedwarsModeStats("doubles", stats, true) +// const { wins_bedwars: threes } = getBedwarsModeStats("3s", stats, true) +// const { wins_bedwars: fours } = getBedwarsModeStats("4s", stats, true) +// +// const max = Math.max(solo, doubles, threes, fours) +// +// switch (max) { +// case solo: +// return "solo" +// case doubles: +// return "doubles" +// case threes: +// return "3s" +// case fours: +// return "4s" +// default: +// return null +// } +// } + +export function getDuelsModeStats(mode: Mode, stats: NonNullable) { + return duelsModeStats(mode, stats) +} + +function duelsModeStats(index: typeof MODES[number]["id"], stats: NonNullable) { + return [ + stats[`${index}_kills`], + stats[`${index}_deaths`], + formatNumber(devide(stats[`${index}_kills`], stats[`${index}_deaths`])), + stats[`${index}_wins`], + stats[`${index}_losses`], + formatNumber(devide(stats[`${index}_wins`], stats[`${index}_losses`])), + stats[`current_winstreak_mode_${index}`] ?? -1, + stats[`best_winstreak_mode_${index}`] ?? -1, + formatNumber(devide(stats[`${index}_melee_hits`], stats[`${index}_melee_swings`])), + formatNumber(devide(stats[`${index}_bow_hits`], stats[`${index}_bow_shots`])) + ] +} diff --git a/src/lib/schema/stats.ts b/src/lib/schema/stats.ts index c9b3936..f752c70 100644 --- a/src/lib/schema/stats.ts +++ b/src/lib/schema/stats.ts @@ -1,5 +1,61 @@ import z from "zod" +function bedwarsModeStats() { + const ids = [ + "eight_one", + "eight_two", + "four_three", + "four_four", + "two_four", + "eight_two_rush", + "four_four_rush", + "eight_two_ultimate", + "four_four_ultimate", + "eight_two_lucky", + "four_four_lucky", + "eight_two_voidless", + "four_four_voidless", + "eight_two_armed", + "four_four_armed", + "four_four_swap", + "four_four_underworld", + "castle" + ] as const + + const stats = [ + "winstreak", + "kills_bedwars", + "deaths_bedwars", + "final_kills_bedwars", + "final_deaths_bedwars", + "wins_bedwars", + "losses_bedwars", + "beds_broken_bedwars", + "beds_lost_bedwars" + ] as const + + const entries = new Map>() + const winstreak = new Map>() + + for (const id of ids) { + for (const stat of stats) { + if (stat === "winstreak") { + winstreak.set(`${id}_${stat}`, z.number().optional()) + } else { + entries.set(`${id}_${stat}`, z.number().default(0)) + } + } + } + + type Modes = typeof ids[number] + type Stats = Exclude + + return { + all: Object.fromEntries(entries) as Record<`${Modes}_${Stats}`, z.ZodDefault>, + winstreak: Object.fromEntries(winstreak) as Record<`${Modes}_winstreak`, z.ZodOptional> + } +} + export const bedwarsStatsSchema = z.looseObject({ Experience: z.number().default(0), coins: z.number().default(0), @@ -25,170 +81,39 @@ export const bedwarsStatsSchema = z.looseObject({ doublers: z.number().default(0), room: z.record(z.string(), z.boolean()).optional() }).optional(), - eight_one_winstreak: z.number().optional(), - eight_one_kills_bedwars: z.number().default(0), - eight_one_deaths_bedwars: z.number().default(0), - eight_one_final_kills_bedwars: z.number().default(0), - eight_one_final_deaths_bedwars: z.number().default(0), - eight_one_wins_bedwars: z.number().default(0), - eight_one_losses_bedwars: z.number().default(0), - eight_one_beds_broken_bedwars: z.number().default(0), - eight_one_beds_lost_bedwars: z.number().default(0), - eight_two_winstreak: z.number().optional(), - eight_two_kills_bedwars: z.number().default(0), - eight_two_deaths_bedwars: z.number().default(0), - eight_two_final_kills_bedwars: z.number().default(0), - eight_two_final_deaths_bedwars: z.number().default(0), - eight_two_wins_bedwars: z.number().default(0), - eight_two_losses_bedwars: z.number().default(0), - eight_two_beds_broken_bedwars: z.number().default(0), - eight_two_beds_lost_bedwars: z.number().default(0), - four_three_winstreak: z.number().optional(), - four_three_kills_bedwars: z.number().default(0), - four_three_deaths_bedwars: z.number().default(0), - four_three_final_kills_bedwars: z.number().default(0), - four_three_final_deaths_bedwars: z.number().default(0), - four_three_wins_bedwars: z.number().default(0), - four_three_losses_bedwars: z.number().default(0), - four_three_beds_broken_bedwars: z.number().default(0), - four_three_beds_lost_bedwars: z.number().default(0), - four_four_winstreak: z.number().optional(), - four_four_kills_bedwars: z.number().default(0), - four_four_deaths_bedwars: z.number().default(0), - four_four_final_kills_bedwars: z.number().default(0), - four_four_final_deaths_bedwars: z.number().default(0), - four_four_wins_bedwars: z.number().default(0), - four_four_losses_bedwars: z.number().default(0), - four_four_beds_broken_bedwars: z.number().default(0), - four_four_beds_lost_bedwars: z.number().default(0), - two_four_winstreak: z.number().optional(), - two_four_kills_bedwars: z.number().default(0), - two_four_deaths_bedwars: z.number().default(0), - two_four_final_kills_bedwars: z.number().default(0), - two_four_final_deaths_bedwars: z.number().default(0), - two_four_wins_bedwars: z.number().default(0), - two_four_losses_bedwars: z.number().default(0), - two_four_beds_broken_bedwars: z.number().default(0), - two_four_beds_lost_bedwars: z.number().default(0), - eight_two_rush_winstreak: z.number().optional(), - eight_two_rush_kills_bedwars: z.number().default(0), - eight_two_rush_deaths_bedwars: z.number().default(0), - eight_two_rush_final_kills_bedwars: z.number().default(0), - eight_two_rush_final_deaths_bedwars: z.number().default(0), - eight_two_rush_wins_bedwars: z.number().default(0), - eight_two_rush_losses_bedwars: z.number().default(0), - eight_two_rush_beds_broken_bedwars: z.number().default(0), - eight_two_rush_beds_lost_bedwars: z.number().default(0), - four_four_rush_winstreak: z.number().optional(), - four_four_rush_kills_bedwars: z.number().default(0), - four_four_rush_deaths_bedwars: z.number().default(0), - four_four_rush_final_kills_bedwars: z.number().default(0), - four_four_rush_final_deaths_bedwars: z.number().default(0), - four_four_rush_wins_bedwars: z.number().default(0), - four_four_rush_losses_bedwars: z.number().default(0), - four_four_rush_beds_broken_bedwars: z.number().default(0), - four_four_rush_beds_lost_bedwars: z.number().default(0), - eight_two_ultimate_winstreak: z.number().optional(), - eight_two_ultimate_kills_bedwars: z.number().default(0), - eight_two_ultimate_deaths_bedwars: z.number().default(0), - eight_two_ultimate_final_kills_bedwars: z.number().default(0), - eight_two_ultimate_final_deaths_bedwars: z.number().default(0), - eight_two_ultimate_wins_bedwars: z.number().default(0), - eight_two_ultimate_losses_bedwars: z.number().default(0), - eight_two_ultimate_beds_broken_bedwars: z.number().default(0), - eight_two_ultimate_beds_lost_bedwars: z.number().default(0), - four_four_ultimate_winstreak: z.number().optional(), - four_four_ultimate_kills_bedwars: z.number().default(0), - four_four_ultimate_deaths_bedwars: z.number().default(0), - four_four_ultimate_final_kills_bedwars: z.number().default(0), - four_four_ultimate_final_deaths_bedwars: z.number().default(0), - four_four_ultimate_wins_bedwars: z.number().default(0), - four_four_ultimate_losses_bedwars: z.number().default(0), - four_four_ultimate_beds_broken_bedwars: z.number().default(0), - four_four_ultimate_beds_lost_bedwars: z.number().default(0), - eight_two_lucky_winstreak: z.number().optional(), - eight_two_lucky_kills_bedwars: z.number().default(0), - eight_two_lucky_deaths_bedwars: z.number().default(0), - eight_two_lucky_final_kills_bedwars: z.number().default(0), - eight_two_lucky_final_deaths_bedwars: z.number().default(0), - eight_two_lucky_wins_bedwars: z.number().default(0), - eight_two_lucky_losses_bedwars: z.number().default(0), - eight_two_lucky_beds_broken_bedwars: z.number().default(0), - eight_two_lucky_beds_lost_bedwars: z.number().default(0), - four_four_lucky_winstreak: z.number().optional(), - four_four_lucky_kills_bedwars: z.number().default(0), - four_four_lucky_deaths_bedwars: z.number().default(0), - four_four_lucky_final_kills_bedwars: z.number().default(0), - four_four_lucky_final_deaths_bedwars: z.number().default(0), - four_four_lucky_wins_bedwars: z.number().default(0), - four_four_lucky_losses_bedwars: z.number().default(0), - four_four_lucky_beds_broken_bedwars: z.number().default(0), - four_four_lucky_beds_lost_bedwars: z.number().default(0), - eight_two_voidless_winstreak: z.number().optional(), - eight_two_voidless_kills_bedwars: z.number().default(0), - eight_two_voidless_deaths_bedwars: z.number().default(0), - eight_two_voidless_final_kills_bedwars: z.number().default(0), - eight_two_voidless_final_deaths_bedwars: z.number().default(0), - eight_two_voidless_wins_bedwars: z.number().default(0), - eight_two_voidless_losses_bedwars: z.number().default(0), - eight_two_voidless_beds_broken_bedwars: z.number().default(0), - eight_two_voidless_beds_lost_bedwars: z.number().default(0), - four_four_voidless_winstreak: z.number().optional(), - four_four_voidless_kills_bedwars: z.number().default(0), - four_four_voidless_deaths_bedwars: z.number().default(0), - four_four_voidless_final_kills_bedwars: z.number().default(0), - four_four_voidless_final_deaths_bedwars: z.number().default(0), - four_four_voidless_wins_bedwars: z.number().default(0), - four_four_voidless_losses_bedwars: z.number().default(0), - four_four_voidless_beds_broken_bedwars: z.number().default(0), - four_four_voidless_beds_lost_bedwars: z.number().default(0), - eight_two_armed_winstreak: z.number().optional(), - eight_two_armed_kills_bedwars: z.number().default(0), - eight_two_armed_deaths_bedwars: z.number().default(0), - eight_two_armed_final_kills_bedwars: z.number().default(0), - eight_two_armed_final_deaths_bedwars: z.number().default(0), - eight_two_armed_wins_bedwars: z.number().default(0), - eight_two_armed_losses_bedwars: z.number().default(0), - eight_two_armed_beds_broken_bedwars: z.number().default(0), - eight_two_armed_beds_lost_bedwars: z.number().default(0), - four_four_armed_winstreak: z.number().optional(), - four_four_armed_kills_bedwars: z.number().default(0), - four_four_armed_deaths_bedwars: z.number().default(0), - four_four_armed_final_kills_bedwars: z.number().default(0), - four_four_armed_final_deaths_bedwars: z.number().default(0), - four_four_armed_wins_bedwars: z.number().default(0), - four_four_armed_losses_bedwars: z.number().default(0), - four_four_armed_beds_broken_bedwars: z.number().default(0), - four_four_armed_beds_lost_bedwars: z.number().default(0), - four_four_swap_winstreak: z.number().optional(), - four_four_swap_kills_bedwars: z.number().default(0), - four_four_swap_deaths_bedwars: z.number().default(0), - four_four_swap_final_kills_bedwars: z.number().default(0), - four_four_swap_final_deaths_bedwars: z.number().default(0), - four_four_swap_wins_bedwars: z.number().default(0), - four_four_swap_losses_bedwars: z.number().default(0), - four_four_swap_beds_broken_bedwars: z.number().default(0), - four_four_swap_beds_lost_bedwars: z.number().default(0), - four_four_underworld_winstreak: z.number().optional(), - four_four_underworld_kills_bedwars: z.number().default(0), - four_four_underworld_deaths_bedwars: z.number().default(0), - four_four_underworld_final_kills_bedwars: z.number().default(0), - four_four_underworld_final_deaths_bedwars: z.number().default(0), - four_four_underworld_wins_bedwars: z.number().default(0), - four_four_underworld_losses_bedwars: z.number().default(0), - four_four_underworld_beds_broken_bedwars: z.number().default(0), - four_four_underworld_beds_lost_bedwars: z.number().default(0), - castle_winstreak: z.number().optional(), - castle_kills_bedwars: z.number().default(0), - castle_deaths_bedwars: z.number().default(0), - castle_final_kills_bedwars: z.number().default(0), - castle_final_deaths_bedwars: z.number().default(0), - castle_wins_bedwars: z.number().default(0), - castle_losses_bedwars: z.number().default(0), - castle_beds_broken_bedwars: z.number().default(0), - castle_beds_lost_bedwars: z.number().default(0) + ...bedwarsModeStats().all, + ...bedwarsModeStats().winstreak }) +function skywarsModeStats() { + const ids = [ + "solo_normal", + "solo_insane", + "team_normal", + "team_insane", + "mega", + "mega_doubles", + "ranked_normal" + ] as const + + const stats = [ + "kills", + "deaths", + "wins", + "losses" + ] as const + + const entries = new Map>() + + for (const id of ids) { + for (const stat of stats) { + entries.set(`${stat}_${id}`, z.number().default(0)) + } + } + + return Object.fromEntries(entries) as Record<`${typeof stats[number]}_${typeof ids[number]}`, z.ZodDefault> +} + export const skywarsStatsSchema = z.looseObject({ skywars_experience: z.number().default(0), selected_prestige_icon: z.string().optional(), @@ -219,34 +144,6 @@ export const skywarsStatsSchema = z.looseObject({ paid_souls: z.number().default(0), soul_well: z.number().default(0), packages: z.array(z.string()), - kills_solo_normal: z.number().default(0), - deaths_solo_normal: z.number().default(0), - wins_solo_normal: z.number().default(0), - losses_solo_normal: z.number().default(0), - kills_solo_insane: z.number().default(0), - deaths_solo_insane: z.number().default(0), - wins_solo_insane: z.number().default(0), - losses_solo_insane: z.number().default(0), - kills_team_normal: z.number().default(0), - deaths_team_normal: z.number().default(0), - wins_team_normal: z.number().default(0), - losses_team_normal: z.number().default(0), - kills_team_insane: z.number().default(0), - deaths_team_insane: z.number().default(0), - wins_team_insane: z.number().default(0), - losses_team_insane: z.number().default(0), - kills_mega: z.number().default(0), - deaths_mega: z.number().default(0), - wins_mega: z.number().default(0), - losses_mega: z.number().default(0), - kills_mega_doubles: z.number().default(0), - deaths_mega_doubles: z.number().default(0), - wins_mega_doubles: z.number().default(0), - losses_mega_doubles: z.number().default(0), - kills_ranked_normal: z.number().default(0), - deaths_ranked_normal: z.number().default(0), - wins_ranked_normal: z.number().default(0), - losses_ranked_normal: z.number().default(0), shard: z.number().default(0), opals: z.number().default(0), heads_eww: z.number().default(0), @@ -266,9 +163,89 @@ export const skywarsStatsSchema = z.looseObject({ mode: z.string(), sacrifice: z.string() })) - }).optional() + }).optional(), + ...skywarsModeStats() }) +function duelsModeStats() { + const ids = [ + "uhc_duel", + "uhc_doubles", + "uhc_four", + "uhc_meetup", + "op_duel", + "op_doubles", + "sw_duel", + "sw_doubles", + "bow_duel", + "blitz_duel", + "mw_duel", + "mw_doubles", + "sumo_duel", + "bowspleef_duel", + "parkour_eight", + "boxing_duel", + "classic_duel", + "potion_duel", + "combo_duel", + "bridge_duel", + "bridge_doubles", + "bridge_threes", + "bridge_four", + "bridge_2v2v2v2", + "bridge_3v3v3v3", + "capture_threes", + "duel_arena" + ] as const + + const stats = [ + "kills", + "deaths", + "wins", + "losses", + "melee_swings", + "melee_hits", + "bow_shots", + "bow_hits", + "current_winstreak_mode", + "best_winstreak_mode", + "goals" + ] as const + + const entries = new Map>() + const ws = new Map>() + const bestWs = new Map>() + const bridge = new Map>() + + for (const id of ids) { + for (const stat of stats) { + if (id.startsWith("bridge_") && stat === "goals") { + bridge.set(`${id}_${stat}`, z.number().default(0)) + continue + } + + if (stat === "current_winstreak_mode") { + ws.set(`${stat}_${id}`, z.number().optional()) + } else if (stat === "best_winstreak_mode") { + bestWs.set(`${stat}_${id}`, z.number().optional()) + } else { + entries.set(`${id}_${stat}`, z.number().default(0)) + } + } + } + + type Modes = typeof ids[number] + type Stats = Exclude + type BridgeModes = Extract + + return { + all: Object.fromEntries(entries) as Record<`${Modes}_${Stats}`, z.ZodDefault>, + ws: Object.fromEntries(ws) as Record<`current_winstreak_mode_${Modes}`, z.ZodOptional>, + bestWs: Object.fromEntries(bestWs) as Record<`best_winstreak_mode_${Modes}`, z.ZodOptional>, + bridge: Object.fromEntries(bridge) as Record<`${BridgeModes}_goals`, z.ZodDefault> + } +} + export const duelsStatsSchema = z.looseObject({ wins: z.number().default(0), losses: z.number().default(0), @@ -293,58 +270,8 @@ export const duelsStatsSchema = z.looseObject({ all_modes_celestial_title_prestige: z.number().default(-1), all_modes_divine_title_prestige: z.number().default(-1), all_modes_ascended_title_prestige: z.number().default(-1), - uhc_duel_wins: z.number().default(0), - uhc_doubles_wins: z.number().default(0), - uhc_four_wins: z.number().default(0), - uhc_meetup_wins: z.number().default(0), - op_duel_wins: z.number().default(0), - op_doubles_wins: z.number().default(0), - sw_duel_wins: z.number().default(0), - sw_doubles_wins: z.number().default(0), - bow_duel_wins: z.number().default(0), - blitz_duel_wins: z.number().default(0), - mw_duel_wins: z.number().default(0), - mw_doubles_wins: z.number().default(0), - sumo_duel_wins: z.number().default(0), - bowspleef_duel_wins: z.number().default(0), - parkour_eight_wins: z.number().default(0), - boxing_duel_wins: z.number().default(0), - classic_duel_wins: z.number().default(0), - potion_duel_wins: z.number().default(0), - combo_duel_wins: z.number().default(0), - bridge_duel_wins: z.number().default(0), - bridge_doubles_wins: z.number().default(0), - bridge_threes_wins: z.number().default(0), - bridge_four_wins: z.number().default(0), - bridge_2v2v2v2_wins: z.number().default(0), - bridge_3v3v3v3_wins: z.number().default(0), - capture_threes_wins: z.number().default(0), - duel_arena_wins: z.number().default(0), - uhc_duel_losses: z.number().default(0), - uhc_doubles_losses: z.number().default(0), - uhc_four_losses: z.number().default(0), - uhc_meetup_losses: z.number().default(0), - op_duel_losses: z.number().default(0), - op_doubles_losses: z.number().default(0), - sw_duel_losses: z.number().default(0), - sw_doubles_losses: z.number().default(0), - bow_duel_losses: z.number().default(0), - blitz_duel_losses: z.number().default(0), - mw_duel_losses: z.number().default(0), - mw_doubles_losses: z.number().default(0), - sumo_duel_losses: z.number().default(0), - bowspleef_duel_losses: z.number().default(0), - parkour_eight_losses: z.number().default(0), - boxing_duel_losses: z.number().default(0), - classic_duel_losses: z.number().default(0), - potion_duel_losses: z.number().default(0), - combo_duel_losses: z.number().default(0), - bridge_duel_losses: z.number().default(0), - bridge_doubles_losses: z.number().default(0), - bridge_threes_losses: z.number().default(0), - bridge_four_losses: z.number().default(0), - bridge_2v2v2v2_losses: z.number().default(0), - bridge_3v3v3v3_losses: z.number().default(0), - capture_threes_losses: z.number().default(0), - duel_arena_losses: z.number().default(0) + ...duelsModeStats().all, + ...duelsModeStats().ws, + ...duelsModeStats().bestWs, + ...duelsModeStats().bridge })