diff --git a/app/db/tables.ts b/app/db/tables.ts index 2d3e9b4c4..8e523c2b0 100644 --- a/app/db/tables.ts +++ b/app/db/tables.ts @@ -622,6 +622,8 @@ export interface TournamentTeam { noScreen: Generated; droppedOut: Generated; seed: number | null; + /** For formats that have many starting brackets, where should the team start? */ + startingBracketIdx: number | null; activeRosterUserIds: ColumnType< number[] | null, string | null, diff --git a/app/features/calendar/CalendarRepository.server.ts b/app/features/calendar/CalendarRepository.server.ts index aed9bb941..f4dc98712 100644 --- a/app/features/calendar/CalendarRepository.server.ts +++ b/app/features/calendar/CalendarRepository.server.ts @@ -695,6 +695,19 @@ export async function update(args: UpdateArgs) { .returning("mapPickingStyle") .executeTakeFirstOrThrow(); + if ( + Progression.changedBracketProgressionFormat( + existingBracketProgression, + args.bracketProgression, + ) + ) { + await trx + .updateTable("TournamentTeam") + .set({ startingBracketIdx: null }) + .where("tournamentId", "=", tournamentId) + .execute(); + } + mapPickingStyle = _mapPickingStyle; } diff --git a/app/features/calendar/components/BracketProgressionSelector.tsx b/app/features/calendar/components/BracketProgressionSelector.tsx index 2a77c2e3f..8b86c5250 100644 --- a/app/features/calendar/components/BracketProgressionSelector.tsx +++ b/app/features/calendar/components/BracketProgressionSelector.tsx @@ -181,7 +181,7 @@ function TournamentFormatBracketSelector({ /> - {!isFirstBracket ? ( + {bracket.sources ? (
) : null} - {!isFirstBracket ? ( + {bracket.sources ? (
{" "}
- {isFirstBracket ? ( + {!isFirstBracket ? ( +
+ + updateBracket({ + sources: checked ? [] : undefined, + requiresCheckIn: false, + startTime: undefined, + }) + } + disabled={bracket.disabled} + /> + +
+ ) : null} + {!bracket.sources ? ( {isInvitationalTournament ? ( <>Participants added by the organizer diff --git a/app/features/tournament-bracket/core/Progression.test.ts b/app/features/tournament-bracket/core/Progression.test.ts index f08c453ae..6c6f48f70 100644 --- a/app/features/tournament-bracket/core/Progression.test.ts +++ b/app/features/tournament-bracket/core/Progression.test.ts @@ -419,21 +419,6 @@ describe("validatedSources - other rules", () => { expect(error.type).toBe("NO_DE_POSITIVE"); expect((error as any).bracketIdx).toEqual(1); }); - - it("throws an error if many missing sources", () => { - expect(() => - getValidatedBrackets([ - { - settings: {}, - type: "round_robin", - }, - { - settings: {}, - type: "single_elimination", - }, - ]), - ).toThrow(); - }); }); describe("isFinals", () => { diff --git a/app/features/tournament-bracket/core/Progression.ts b/app/features/tournament-bracket/core/Progression.ts index 8990134ab..f4a5ecde2 100644 --- a/app/features/tournament-bracket/core/Progression.ts +++ b/app/features/tournament-bracket/core/Progression.ts @@ -173,8 +173,6 @@ export function validatedBrackets( throw e; } - validateOnlyOneEntry(parsed); - const validationError = bracketsToValidationError(parsed); if (validationError) { @@ -184,16 +182,6 @@ export function validatedBrackets( return parsed; } -function validateOnlyOneEntry(brackets: ParsedBracket[]) { - const entryBracketCount = brackets.filter( - (bracket) => !bracket.sources, - ).length; - - if (entryBracketCount !== 1) { - throw new Error("Only one bracket can have no sources"); - } -} - /** Checks parsed brackets for any errors related to how the progression is laid out */ export function bracketsToValidationError( brackets: ParsedBracket[], diff --git a/app/features/tournament-bracket/core/Tournament.test.ts b/app/features/tournament-bracket/core/Tournament.test.ts index bcf8f7453..80358395e 100644 --- a/app/features/tournament-bracket/core/Tournament.test.ts +++ b/app/features/tournament-bracket/core/Tournament.test.ts @@ -8,6 +8,11 @@ import { PADDLING_POOL_257, } from "./tests/mocks"; import { SWIM_OR_SINK_167 } from "./tests/mocks-sos"; +import { + progressions, + testTournament, + tournamentCtxTeam, +} from "./tests/test-utils"; describe("Follow-up bracket progression", () => { const tournamentPP257 = new Tournament(PADDLING_POOL_257()); @@ -355,3 +360,44 @@ describe("Bracket progression override", () => { expect(tournament.brackets[1].seeding?.at(-1)).toBe(14737); }); }); + +describe("Adjusting team starting bracket", () => { + const createTournament = (teamStartingBracketIdx: (number | null)[]) => { + return testTournament({ + ctx: { + teams: teamStartingBracketIdx.map((startingBracketIdx, i) => + tournamentCtxTeam(i + 1, { startingBracketIdx }), + ), + settings: { + bracketProgression: progressions.manyStartBrackets, + }, + }, + }); + }; + + it("defaults to bracket idx = 0", () => { + const tournament = createTournament([null, null, null, null]); + + expect(tournament.brackets[0].participantTournamentTeamIds).toHaveLength(4); + }); + + it("setting starting bracket idx has an effect", () => { + const tournament = createTournament([0, 0, 1, 1]); + + expect(tournament.brackets[0].participantTournamentTeamIds).toHaveLength(2); + expect(tournament.brackets[1].participantTournamentTeamIds).toHaveLength(2); + }); + + it("handles too high bracket idx gracefully", () => { + const tournament = createTournament([0, 0, 0, 10]); + + expect(tournament.brackets[0].participantTournamentTeamIds).toHaveLength(4); + }); + + it("handles bracket idx is not a valid starting bracket idx gracefully", () => { + // 2 is not valid because it is a follow-up bracket + const tournament = createTournament([0, 0, 0, 2]); + + expect(tournament.brackets[0].participantTournamentTeamIds).toHaveLength(4); + }); +}); diff --git a/app/features/tournament-bracket/core/Tournament.ts b/app/features/tournament-bracket/core/Tournament.ts index e87ebafdf..d7db20474 100644 --- a/app/features/tournament-bracket/core/Tournament.ts +++ b/app/features/tournament-bracket/core/Tournament.ts @@ -163,10 +163,7 @@ export class Tournament { } else if (type === "swiss") { const { teams, relevantMatchesFinished } = sources ? this.resolveTeamsFromSources(sources, bracketIdx) - : { - teams: this.ctx.teams.map((team) => team.id), - relevantMatchesFinished: true, - }; + : this.resolveTeamsFromSignups(bracketIdx); const { checkedInTeams, notCheckedInTeams } = this.divideTeamsToCheckedInAndNotCheckedIn({ @@ -210,10 +207,7 @@ export class Tournament { } else { const { teams, relevantMatchesFinished } = sources ? this.resolveTeamsFromSources(sources, bracketIdx) - : { - teams: this.ctx.teams.map((team) => team.id), - relevantMatchesFinished: true, - }; + : this.resolveTeamsFromSignups(bracketIdx); const { checkedInTeams, notCheckedInTeams } = this.divideTeamsToCheckedInAndNotCheckedIn({ @@ -332,6 +326,34 @@ export class Tournament { }; } + private resolveTeamsFromSignups(bracketIdx: number) { + const teams = this.isMultiStartingBracket + ? this.ctx.teams.filter((team) => { + // 0 is the default + if (typeof team.startingBracketIdx !== "number") { + return bracketIdx === 0; + } + + const startingBracket = this.ctx.settings.bracketProgression.at( + team.startingBracketIdx, + ); + if (!startingBracket || startingBracket.sources) { + logger.warn( + "resolveTeamsFromSignups: Starting bracket index invalid", + ); + return bracketIdx === 0; + } + + return team.startingBracketIdx === bracketIdx; + }) + : this.ctx.teams; + + return { + teams: teams.map((team) => team.id), + relevantMatchesFinished: true, + }; + } + private avoidReplaysOfPreviousBracketOpponent( teams: number[], bracket: { @@ -995,6 +1017,15 @@ export class Tournament { return bracket; } + get isMultiStartingBracket() { + let count = 0; + for (const bracket of this.ctx.settings.bracketProgression) { + if (!bracket.sources) count++; + } + + return count > 1; + } + ownedTeamByUser( user: OptionalIdObject, ): ((typeof this.ctx.teams)[number] & { inviteCode: string }) | null { diff --git a/app/features/tournament-bracket/core/summarizer.test.ts b/app/features/tournament-bracket/core/summarizer.test.ts index 19e91405d..3158f2f91 100644 --- a/app/features/tournament-bracket/core/summarizer.test.ts +++ b/app/features/tournament-bracket/core/summarizer.test.ts @@ -16,6 +16,7 @@ describe("tournamentSummary()", () => { id: teamId, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, mapPool: [], members: userIds.map((userId) => ({ country: null, diff --git a/app/features/tournament-bracket/core/tests/mocks-li.ts b/app/features/tournament-bracket/core/tests/mocks-li.ts index 97d8691f9..eff01d39c 100644 --- a/app/features/tournament-bracket/core/tests/mocks-li.ts +++ b/app/features/tournament-bracket/core/tests/mocks-li.ts @@ -7575,6 +7575,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733157607, activeRosterUserIds: [25875, 21063, 11226, 31597], pickupAvatarUrl: null, @@ -7664,6 +7665,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733157629, activeRosterUserIds: [14837, 27260, 42704, 9379], pickupAvatarUrl: null, @@ -7753,6 +7755,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 1, inviteCode: null, + startingBracketIdx: null, createdAt: 1733161494, activeRosterUserIds: [34424, 31195, 31395, 26103], pickupAvatarUrl: null, @@ -7842,6 +7845,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733166918, activeRosterUserIds: null, pickupAvatarUrl: null, @@ -7919,6 +7923,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733166213, activeRosterUserIds: [32160, 29267, 25591, 36962], pickupAvatarUrl: null, @@ -8003,6 +8008,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 1, inviteCode: null, + startingBracketIdx: null, createdAt: 1733189945, activeRosterUserIds: [12418, 34355, 2319, 7430], pickupAvatarUrl: null, @@ -8092,6 +8098,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733244862, activeRosterUserIds: [29425, 31524, 35674, 26285], pickupAvatarUrl: null, @@ -8181,6 +8188,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733282085, activeRosterUserIds: [26747, 27292, 5708, 6309], pickupAvatarUrl: null, @@ -8282,6 +8290,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733291438, activeRosterUserIds: [24459, 40851, 23974, 43608], pickupAvatarUrl: null, @@ -8383,6 +8392,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 1, inviteCode: null, + startingBracketIdx: null, createdAt: 1733439755, activeRosterUserIds: null, pickupAvatarUrl: null, @@ -8460,6 +8470,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733485884, activeRosterUserIds: [30686, 1961, 30685, 22396], pickupAvatarUrl: null, @@ -8561,6 +8572,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733937993, activeRosterUserIds: [12434, 30263, 5861, 24275], pickupAvatarUrl: null, @@ -8662,6 +8674,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733166818, activeRosterUserIds: [32670, 38046, 42638, 34589], pickupAvatarUrl: "pickup-logo-Hj-Us_Roj5Ksfv000ceBo-1733166818832.webp", @@ -8751,6 +8764,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733167616, activeRosterUserIds: [45102, 26711, 41739, 4533], pickupAvatarUrl: null, @@ -8840,6 +8854,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 1, inviteCode: null, + startingBracketIdx: null, createdAt: 1733201503, activeRosterUserIds: [20807, 31556, 33373, 42703], pickupAvatarUrl: null, @@ -8941,6 +8956,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733218069, activeRosterUserIds: [26509, 7959, 7690, 7958], pickupAvatarUrl: null, @@ -9030,6 +9046,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733319202, activeRosterUserIds: [10714, 21685, 8840, 10028], pickupAvatarUrl: null, @@ -9131,6 +9148,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 1, inviteCode: null, + startingBracketIdx: null, createdAt: 1733471556, activeRosterUserIds: [17532, 30204, 36007, 38896], pickupAvatarUrl: null, @@ -9220,6 +9238,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733501938, activeRosterUserIds: [30495, 43073, 30488, 45295], pickupAvatarUrl: null, @@ -9309,6 +9328,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733622364, activeRosterUserIds: null, pickupAvatarUrl: null, @@ -9380,6 +9400,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733635706, activeRosterUserIds: null, pickupAvatarUrl: null, @@ -9457,6 +9478,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733671856, activeRosterUserIds: null, pickupAvatarUrl: null, @@ -9529,6 +9551,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733810204, activeRosterUserIds: [1959, 17352, 33954, 22403], pickupAvatarUrl: "pickup-logo-3KZntw8OZ9LkW4XqZRLS9-1733810204048.webp", @@ -9613,6 +9636,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733889961, activeRosterUserIds: [6696, 32107, 33402, 30619], pickupAvatarUrl: null, @@ -9697,6 +9721,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733892132, activeRosterUserIds: [21670, 8993, 8395, 3566], pickupAvatarUrl: null, @@ -9786,6 +9811,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1734035170, activeRosterUserIds: [24510, 10670, 22577, 31143], pickupAvatarUrl: null, @@ -9875,6 +9901,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1734107844, activeRosterUserIds: [28170, 14309, 17310, 23164], pickupAvatarUrl: null, @@ -9964,6 +9991,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1734132225, activeRosterUserIds: null, pickupAvatarUrl: "pickup-logo-_asHjlVchhJ50PH_mDBtw-1734132224819.webp", @@ -10036,6 +10064,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733194304, activeRosterUserIds: [40505, 29011, 23082, 45036], pickupAvatarUrl: null, @@ -10125,6 +10154,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733195091, activeRosterUserIds: null, pickupAvatarUrl: null, @@ -10202,6 +10232,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733364647, activeRosterUserIds: [22801, 31150, 35354, 27747], pickupAvatarUrl: null, @@ -10291,6 +10322,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733374295, activeRosterUserIds: null, pickupAvatarUrl: null, @@ -10368,6 +10400,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733433864, activeRosterUserIds: null, pickupAvatarUrl: null, @@ -10463,6 +10496,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733513814, activeRosterUserIds: null, pickupAvatarUrl: null, @@ -10540,6 +10574,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733602400, activeRosterUserIds: [10826, 4248, 20419, 11180], pickupAvatarUrl: null, @@ -10629,6 +10664,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733753214, activeRosterUserIds: [27903, 28446, 34634, 30728], pickupAvatarUrl: null, @@ -10718,6 +10754,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733914001, activeRosterUserIds: [32909, 10190, 35922, 40304], pickupAvatarUrl: null, @@ -10819,6 +10856,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733966548, activeRosterUserIds: [35617, 37669, 37436, 35811], pickupAvatarUrl: null, @@ -10908,6 +10946,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1734032213, activeRosterUserIds: null, pickupAvatarUrl: null, @@ -10985,6 +11024,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1734106606, activeRosterUserIds: [37173, 43269, 43623, 16054], pickupAvatarUrl: null, @@ -11074,6 +11114,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1734116765, activeRosterUserIds: [25312, 10378, 46771, 26044], pickupAvatarUrl: null, @@ -11175,6 +11216,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1734125312, activeRosterUserIds: null, pickupAvatarUrl: null, @@ -11252,6 +11294,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1734134382, activeRosterUserIds: [26758, 25689, 42164, 44475], pickupAvatarUrl: null, @@ -11336,6 +11379,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733156802, activeRosterUserIds: [9036, 7434, 3738, 9112], pickupAvatarUrl: null, @@ -11425,6 +11469,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733157391, activeRosterUserIds: [5935, 38204, 3741, 8080], pickupAvatarUrl: null, @@ -11526,6 +11571,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733162274, activeRosterUserIds: null, pickupAvatarUrl: null, @@ -11603,6 +11649,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733367806, activeRosterUserIds: null, pickupAvatarUrl: null, @@ -11680,6 +11727,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733456080, activeRosterUserIds: [10386, 33369, 29617, 22942], pickupAvatarUrl: null, @@ -11769,6 +11817,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733579092, activeRosterUserIds: null, pickupAvatarUrl: null, @@ -11840,6 +11889,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733769667, activeRosterUserIds: [3481, 38022, 41269, 43551], pickupAvatarUrl: null, @@ -11941,6 +11991,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733794148, activeRosterUserIds: [22820, 29636, 27036, 28959], pickupAvatarUrl: null, @@ -12042,6 +12093,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 1, inviteCode: null, + startingBracketIdx: null, createdAt: 1733820540, activeRosterUserIds: null, pickupAvatarUrl: "pickup-logo-t2-mrQNINFqIoFNYuxbmW-1733820600291.webp", @@ -12114,6 +12166,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733825084, activeRosterUserIds: null, pickupAvatarUrl: null, @@ -12191,6 +12244,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 1, inviteCode: null, + startingBracketIdx: null, createdAt: 1733865890, activeRosterUserIds: [15425, 41975, 28938, 8587], pickupAvatarUrl: null, @@ -12280,6 +12334,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 1, inviteCode: null, + startingBracketIdx: null, createdAt: 1733873149, activeRosterUserIds: [40550, 7115, 29674, 30031], pickupAvatarUrl: null, @@ -12381,6 +12436,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733875608, activeRosterUserIds: null, pickupAvatarUrl: null, @@ -12458,6 +12514,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733888417, activeRosterUserIds: null, pickupAvatarUrl: "pickup-logo-c9a1igcMT4m2otyRdTs_0-1733888672873.webp", @@ -12530,6 +12587,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 1, inviteCode: null, + startingBracketIdx: null, createdAt: 1734008857, activeRosterUserIds: [30266, 37341, 22699, 28145], pickupAvatarUrl: null, @@ -12619,6 +12677,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 1, inviteCode: null, + startingBracketIdx: null, createdAt: 1734018352, activeRosterUserIds: null, pickupAvatarUrl: null, @@ -12696,6 +12755,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1734019701, activeRosterUserIds: [35421, 33524, 22500, 32802], pickupAvatarUrl: "pickup-logo-u4oKxXYjamTXZ1x-bgNFp-1734019701188.webp", @@ -12792,6 +12852,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 1, inviteCode: null, + startingBracketIdx: null, createdAt: 1734023441, activeRosterUserIds: [1852, 2898, 25763, 3466], pickupAvatarUrl: null, @@ -12881,6 +12942,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1734099744, activeRosterUserIds: [39098, 22624, 28137, 2769], pickupAvatarUrl: null, @@ -12970,6 +13032,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1734109256, activeRosterUserIds: [29661, 15158, 35067, 31655], pickupAvatarUrl: "pickup-logo-An13SrR78qDNIM2t95ujb-1734109256283.webp", @@ -13066,6 +13129,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1734125682, activeRosterUserIds: [36575, 30425, 32430, 24290], pickupAvatarUrl: null, @@ -13167,6 +13231,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 1, inviteCode: null, + startingBracketIdx: null, createdAt: 1733515005, activeRosterUserIds: null, pickupAvatarUrl: null, @@ -13244,6 +13309,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733521735, activeRosterUserIds: [44772, 38912, 36853, 42599], pickupAvatarUrl: null, @@ -13333,6 +13399,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733525617, activeRosterUserIds: null, pickupAvatarUrl: null, @@ -13410,6 +13477,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733847805, activeRosterUserIds: [33615, 32015, 45778, 32970], pickupAvatarUrl: null, @@ -13499,6 +13567,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733858126, activeRosterUserIds: [34545, 35567, 41108, 41255], pickupAvatarUrl: null, @@ -13588,6 +13657,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733966096, activeRosterUserIds: [39470, 42874, 32878, 25741], pickupAvatarUrl: null, @@ -13677,6 +13747,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1734021147, activeRosterUserIds: [45250, 45174, 6976, 10222], pickupAvatarUrl: "pickup-logo-v3boyVjbFsTyMlQylz4Dn-1734021152539.webp", @@ -13766,6 +13837,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1734040772, activeRosterUserIds: null, pickupAvatarUrl: "pickup-logo-Jx6JnhFJQjOnM10s_79ld-1734041234919.webp", @@ -13843,6 +13915,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 1, inviteCode: null, + startingBracketIdx: null, createdAt: 1734033803, activeRosterUserIds: [27800, 12235, 30044, 29531], pickupAvatarUrl: null, @@ -13932,6 +14005,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1734099612, activeRosterUserIds: [24572, 7058, 37641, 33913], pickupAvatarUrl: "pickup-logo-RrPQW5kG_K1cvjdU5TKcF-1734099611923.webp", @@ -14016,6 +14090,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 1, inviteCode: null, + startingBracketIdx: null, createdAt: 1734113463, activeRosterUserIds: null, pickupAvatarUrl: null, @@ -14093,6 +14168,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1734118202, activeRosterUserIds: null, pickupAvatarUrl: null, @@ -14164,6 +14240,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1734134334, activeRosterUserIds: [11186, 27611, 25952, 23481], pickupAvatarUrl: null, @@ -14253,6 +14330,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 1, inviteCode: null, + startingBracketIdx: null, createdAt: 1733169181, activeRosterUserIds: null, pickupAvatarUrl: null, @@ -14330,6 +14408,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 1, inviteCode: null, + startingBracketIdx: null, createdAt: 1733247691, activeRosterUserIds: null, pickupAvatarUrl: "pickup-logo--fZF6IGlzuuHeotc6Z00p-1733762912138.webp", @@ -14407,6 +14486,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733452618, activeRosterUserIds: null, pickupAvatarUrl: null, @@ -14485,6 +14565,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733481710, activeRosterUserIds: null, pickupAvatarUrl: null, @@ -14568,6 +14649,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733508949, activeRosterUserIds: null, pickupAvatarUrl: null, @@ -14645,6 +14727,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733611261, activeRosterUserIds: null, pickupAvatarUrl: null, @@ -14717,6 +14800,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 0, inviteCode: null, + startingBracketIdx: null, createdAt: 1733841846, activeRosterUserIds: [41943, 46289, 45290, 46394], pickupAvatarUrl: null, @@ -14806,6 +14890,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 0, droppedOut: 1, inviteCode: null, + startingBracketIdx: null, createdAt: 1733878153, activeRosterUserIds: null, pickupAvatarUrl: null, @@ -14883,6 +14968,7 @@ export const LOW_INK_DECEMBER_2024 = (): TournamentData => ({ noScreen: 1, droppedOut: 1, inviteCode: null, + startingBracketIdx: null, createdAt: 1734135144, activeRosterUserIds: null, pickupAvatarUrl: "pickup-logo-obQfxdRnJg0CsbrE6OXdl-1734135144301.webp", diff --git a/app/features/tournament-bracket/core/tests/mocks-sos.ts b/app/features/tournament-bracket/core/tests/mocks-sos.ts index 14b5a2536..b22fa47b5 100644 --- a/app/features/tournament-bracket/core/tests/mocks-sos.ts +++ b/app/features/tournament-bracket/core/tests/mocks-sos.ts @@ -2548,6 +2548,7 @@ export const SWIM_OR_SINK_167 = ( mapPool: [], team: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14800, @@ -2640,6 +2641,7 @@ export const SWIM_OR_SINK_167 = ( mapPool: [], team: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14743, @@ -2744,6 +2746,7 @@ export const SWIM_OR_SINK_167 = ( mapPool: [], team: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14801, @@ -2836,6 +2839,7 @@ export const SWIM_OR_SINK_167 = ( mapPool: [], team: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14792, @@ -2928,6 +2932,7 @@ export const SWIM_OR_SINK_167 = ( mapPool: [], team: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14670, @@ -3049,6 +3054,7 @@ export const SWIM_OR_SINK_167 = ( deletedAt: null, }, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14661, @@ -3158,6 +3164,7 @@ export const SWIM_OR_SINK_167 = ( deletedAt: null, }, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14804, @@ -3267,6 +3274,7 @@ export const SWIM_OR_SINK_167 = ( deletedAt: null, }, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14732, @@ -3364,6 +3372,7 @@ export const SWIM_OR_SINK_167 = ( deletedAt: null, }, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14747, @@ -3468,6 +3477,7 @@ export const SWIM_OR_SINK_167 = ( deletedAt: null, }, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14748, @@ -3572,6 +3582,7 @@ export const SWIM_OR_SINK_167 = ( mapPool: [], team: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14803, @@ -3664,6 +3675,7 @@ export const SWIM_OR_SINK_167 = ( mapPool: [], team: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14795, @@ -3773,6 +3785,7 @@ export const SWIM_OR_SINK_167 = ( deletedAt: null, }, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14445, @@ -3894,6 +3907,7 @@ export const SWIM_OR_SINK_167 = ( deletedAt: null, }, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14810, @@ -3948,6 +3962,7 @@ export const SWIM_OR_SINK_167 = ( mapPool: [], team: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14777, @@ -4040,6 +4055,7 @@ export const SWIM_OR_SINK_167 = ( mapPool: [], team: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14805, @@ -4132,6 +4148,7 @@ export const SWIM_OR_SINK_167 = ( mapPool: [], team: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14806, @@ -4224,6 +4241,7 @@ export const SWIM_OR_SINK_167 = ( mapPool: [], team: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14653, @@ -4345,6 +4363,7 @@ export const SWIM_OR_SINK_167 = ( deletedAt: null, }, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14708, @@ -4454,6 +4473,7 @@ export const SWIM_OR_SINK_167 = ( deletedAt: null, }, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14715, @@ -4551,6 +4571,7 @@ export const SWIM_OR_SINK_167 = ( deletedAt: null, }, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14796, @@ -4643,6 +4664,7 @@ export const SWIM_OR_SINK_167 = ( mapPool: [], team: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14797, @@ -4735,6 +4757,7 @@ export const SWIM_OR_SINK_167 = ( mapPool: [], team: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14750, @@ -4818,6 +4841,7 @@ export const SWIM_OR_SINK_167 = ( deletedAt: null, }, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14809, @@ -4927,6 +4951,7 @@ export const SWIM_OR_SINK_167 = ( deletedAt: null, }, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14709, @@ -5024,6 +5049,7 @@ export const SWIM_OR_SINK_167 = ( deletedAt: null, }, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14783, @@ -5071,6 +5097,7 @@ export const SWIM_OR_SINK_167 = ( deletedAt: null, }, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14702, @@ -5163,6 +5190,7 @@ export const SWIM_OR_SINK_167 = ( mapPool: [], team: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14735, @@ -5272,6 +5300,7 @@ export const SWIM_OR_SINK_167 = ( deletedAt: null, }, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14798, @@ -5376,6 +5405,7 @@ export const SWIM_OR_SINK_167 = ( mapPool: [], team: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14663, @@ -5473,6 +5503,7 @@ export const SWIM_OR_SINK_167 = ( deletedAt: null, }, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14517, @@ -5582,6 +5613,7 @@ export const SWIM_OR_SINK_167 = ( deletedAt: null, }, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14741, @@ -5691,6 +5723,7 @@ export const SWIM_OR_SINK_167 = ( deletedAt: null, }, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14711, @@ -5774,6 +5807,7 @@ export const SWIM_OR_SINK_167 = ( deletedAt: null, }, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14655, @@ -5895,6 +5929,7 @@ export const SWIM_OR_SINK_167 = ( deletedAt: null, }, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14634, @@ -5966,6 +6001,7 @@ export const SWIM_OR_SINK_167 = ( deletedAt: null, }, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14799, @@ -6063,6 +6099,7 @@ export const SWIM_OR_SINK_167 = ( deletedAt: null, }, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14784, @@ -6129,6 +6166,7 @@ export const SWIM_OR_SINK_167 = ( mapPool: [], team: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14733, @@ -6221,6 +6259,7 @@ export const SWIM_OR_SINK_167 = ( mapPool: [], team: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14611, @@ -6304,6 +6343,7 @@ export const SWIM_OR_SINK_167 = ( deletedAt: null, }, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14713, @@ -6408,6 +6448,7 @@ export const SWIM_OR_SINK_167 = ( mapPool: [], team: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14687, @@ -6517,6 +6558,7 @@ export const SWIM_OR_SINK_167 = ( deletedAt: null, }, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14742, @@ -6638,6 +6680,7 @@ export const SWIM_OR_SINK_167 = ( deletedAt: null, }, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14764, @@ -6730,6 +6773,7 @@ export const SWIM_OR_SINK_167 = ( mapPool: [], team: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14802, @@ -6834,6 +6878,7 @@ export const SWIM_OR_SINK_167 = ( mapPool: [], team: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14696, @@ -6943,6 +6988,7 @@ export const SWIM_OR_SINK_167 = ( deletedAt: null, }, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14808, @@ -7035,6 +7081,7 @@ export const SWIM_OR_SINK_167 = ( mapPool: [], team: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14620, @@ -7151,6 +7198,7 @@ export const SWIM_OR_SINK_167 = ( mapPool: [], team: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14737, @@ -7260,6 +7308,7 @@ export const SWIM_OR_SINK_167 = ( deletedAt: null, }, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14503, @@ -7331,6 +7380,7 @@ export const SWIM_OR_SINK_167 = ( deletedAt: null, }, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14739, @@ -7423,6 +7473,7 @@ export const SWIM_OR_SINK_167 = ( mapPool: [], team: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, { id: 14607, @@ -7520,6 +7571,7 @@ export const SWIM_OR_SINK_167 = ( deletedAt: null, }, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, }, ], tieBreakerMapPool: [], diff --git a/app/features/tournament-bracket/core/tests/mocks.ts b/app/features/tournament-bracket/core/tests/mocks.ts index f4552f8b5..7e27ab731 100644 --- a/app/features/tournament-bracket/core/tests/mocks.ts +++ b/app/features/tournament-bracket/core/tests/mocks.ts @@ -2109,6 +2109,7 @@ export const PADDLING_POOL_257 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709743534, @@ -2223,6 +2224,7 @@ export const PADDLING_POOL_257 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709737918, @@ -2349,6 +2351,7 @@ export const PADDLING_POOL_257 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709743523, @@ -2463,6 +2466,7 @@ export const PADDLING_POOL_257 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709743262, @@ -2577,6 +2581,7 @@ export const PADDLING_POOL_257 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709741396, @@ -2701,6 +2706,7 @@ export const PADDLING_POOL_257 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709711811, @@ -2825,6 +2831,7 @@ export const PADDLING_POOL_257 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709738831, @@ -2948,6 +2955,7 @@ export const PADDLING_POOL_257 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709737837, @@ -3059,6 +3067,7 @@ export const PADDLING_POOL_257 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709741719, @@ -3196,6 +3205,7 @@ export const PADDLING_POOL_257 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709730354, @@ -3320,6 +3330,7 @@ export const PADDLING_POOL_257 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709745630, @@ -3441,6 +3452,7 @@ export const PADDLING_POOL_257 = () => prefersNotToHost: 1, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709592381, @@ -3575,6 +3587,7 @@ export const PADDLING_POOL_257 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709723749, @@ -3698,6 +3711,7 @@ export const PADDLING_POOL_257 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709668399, @@ -3832,6 +3846,7 @@ export const PADDLING_POOL_257 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709735267, @@ -3947,6 +3962,7 @@ export const PADDLING_POOL_257 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709745849, @@ -4062,6 +4078,7 @@ export const PADDLING_POOL_257 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709742258, @@ -4181,6 +4198,7 @@ export const PADDLING_POOL_257 = () => prefersNotToHost: 1, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709738744, @@ -4303,6 +4321,7 @@ export const PADDLING_POOL_257 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709746054, @@ -4415,6 +4434,7 @@ export const PADDLING_POOL_257 = () => prefersNotToHost: 1, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709744894, @@ -4525,6 +4545,7 @@ export const PADDLING_POOL_257 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709728278, @@ -4635,6 +4656,7 @@ export const PADDLING_POOL_257 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709715006, @@ -4745,6 +4767,7 @@ export const PADDLING_POOL_257 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709660578, @@ -4860,6 +4883,7 @@ export const PADDLING_POOL_257 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709721869, @@ -4984,6 +5008,7 @@ export const PADDLING_POOL_257 = () => prefersNotToHost: 1, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709743633, @@ -5099,6 +5124,7 @@ export const PADDLING_POOL_257 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709738747, @@ -5226,6 +5252,7 @@ export const PADDLING_POOL_257 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709626047, @@ -5348,6 +5375,7 @@ export const PADDLING_POOL_257 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709727951, @@ -5458,6 +5486,7 @@ export const PADDLING_POOL_257 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709741482, @@ -5589,6 +5618,7 @@ export const PADDLING_POOL_257 = () => prefersNotToHost: 1, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709744451, @@ -5704,6 +5734,7 @@ export const PADDLING_POOL_257 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709726536, @@ -5814,6 +5845,7 @@ export const PADDLING_POOL_257 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709558706, @@ -5929,6 +5961,7 @@ export const PADDLING_POOL_257 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709744323, @@ -6056,6 +6089,7 @@ export const PADDLING_POOL_257 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709677397, @@ -6166,6 +6200,7 @@ export const PADDLING_POOL_257 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1709618711, @@ -8000,6 +8035,7 @@ export const PADDLING_POOL_255 = () => prefersNotToHost: 1, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708476597, @@ -8113,6 +8149,7 @@ export const PADDLING_POOL_255 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708535137, @@ -8227,6 +8264,7 @@ export const PADDLING_POOL_255 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708533764, @@ -8350,6 +8388,7 @@ export const PADDLING_POOL_255 = () => prefersNotToHost: 1, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708537512, @@ -8476,6 +8515,7 @@ export const PADDLING_POOL_255 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708533309, @@ -8590,6 +8630,7 @@ export const PADDLING_POOL_255 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708430641, @@ -8716,6 +8757,7 @@ export const PADDLING_POOL_255 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708536306, @@ -8827,6 +8869,7 @@ export const PADDLING_POOL_255 = () => prefersNotToHost: 1, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708526368, @@ -8939,6 +8982,7 @@ export const PADDLING_POOL_255 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708506060, @@ -9075,6 +9119,7 @@ export const PADDLING_POOL_255 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708526814, @@ -9183,6 +9228,7 @@ export const PADDLING_POOL_255 = () => prefersNotToHost: 1, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708466421, @@ -9305,6 +9351,7 @@ export const PADDLING_POOL_255 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708377426, @@ -9424,6 +9471,7 @@ export const PADDLING_POOL_255 = () => prefersNotToHost: 1, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708448289, @@ -9558,6 +9606,7 @@ export const PADDLING_POOL_255 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708532602, @@ -9668,6 +9717,7 @@ export const PADDLING_POOL_255 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708535205, @@ -9790,6 +9840,7 @@ export const PADDLING_POOL_255 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708515945, @@ -9900,6 +9951,7 @@ export const PADDLING_POOL_255 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708453334, @@ -10007,6 +10059,7 @@ export const PADDLING_POOL_255 = () => prefersNotToHost: 1, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708522730, @@ -10129,6 +10182,7 @@ export const PADDLING_POOL_255 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708375443, @@ -10251,6 +10305,7 @@ export const PADDLING_POOL_255 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708532665, @@ -10366,6 +10421,7 @@ export const PADDLING_POOL_255 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708364254, @@ -10493,6 +10549,7 @@ export const PADDLING_POOL_255 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708464101, @@ -10617,6 +10674,7 @@ export const PADDLING_POOL_255 = () => prefersNotToHost: 1, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708520249, @@ -10739,6 +10797,7 @@ export const PADDLING_POOL_255 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708535804, @@ -10849,6 +10908,7 @@ export const PADDLING_POOL_255 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708535891, @@ -10971,6 +11031,7 @@ export const PADDLING_POOL_255 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708521749, @@ -11093,6 +11154,7 @@ export const PADDLING_POOL_255 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708536584, @@ -11203,6 +11265,7 @@ export const PADDLING_POOL_255 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708537772, @@ -11343,6 +11406,7 @@ export const PADDLING_POOL_255 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708379916, @@ -11465,6 +11529,7 @@ export const PADDLING_POOL_255 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708519753, @@ -11592,6 +11657,7 @@ export const PADDLING_POOL_255 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708534312, @@ -11716,6 +11782,7 @@ export const PADDLING_POOL_255 = () => prefersNotToHost: 1, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708531929, @@ -11826,6 +11893,7 @@ export const PADDLING_POOL_255 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708477155, @@ -11941,6 +12009,7 @@ export const PADDLING_POOL_255 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708531564, @@ -12092,6 +12161,7 @@ export const PADDLING_POOL_255 = () => team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1708503356, @@ -14202,6 +14272,7 @@ export const IN_THE_ZONE_32 = ({ team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1707443313, @@ -14303,6 +14374,7 @@ export const IN_THE_ZONE_32 = ({ team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1707366405, @@ -14404,6 +14476,7 @@ export const IN_THE_ZONE_32 = ({ team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1706912643, @@ -14505,6 +14578,7 @@ export const IN_THE_ZONE_32 = ({ team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1707359335, @@ -14632,6 +14706,7 @@ export const IN_THE_ZONE_32 = ({ team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1707171426, @@ -14746,6 +14821,7 @@ export const IN_THE_ZONE_32 = ({ team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1707342696, @@ -14860,6 +14936,7 @@ export const IN_THE_ZONE_32 = ({ team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1707513942, @@ -14987,6 +15064,7 @@ export const IN_THE_ZONE_32 = ({ team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1707526815, @@ -15114,6 +15192,7 @@ export const IN_THE_ZONE_32 = ({ team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1707583385, @@ -15215,6 +15294,7 @@ export const IN_THE_ZONE_32 = ({ team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1707486395, @@ -15316,6 +15396,7 @@ export const IN_THE_ZONE_32 = ({ team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1707513290, @@ -15417,6 +15498,7 @@ export const IN_THE_ZONE_32 = ({ team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1707531084, @@ -15518,6 +15600,7 @@ export const IN_THE_ZONE_32 = ({ team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1707568466, @@ -15632,6 +15715,7 @@ export const IN_THE_ZONE_32 = ({ team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1707481625, @@ -15733,6 +15817,7 @@ export const IN_THE_ZONE_32 = ({ team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1707530166, @@ -15833,6 +15918,7 @@ export const IN_THE_ZONE_32 = ({ team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1707181792, @@ -15947,6 +16033,7 @@ export const IN_THE_ZONE_32 = ({ team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1707550321, @@ -16066,6 +16153,7 @@ export const IN_THE_ZONE_32 = ({ team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1707575096, @@ -16180,6 +16268,7 @@ export const IN_THE_ZONE_32 = ({ team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1707569490, @@ -16307,6 +16396,7 @@ export const IN_THE_ZONE_32 = ({ team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1707537425, @@ -16408,6 +16498,7 @@ export const IN_THE_ZONE_32 = ({ team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1707564691, @@ -16538,6 +16629,7 @@ export const IN_THE_ZONE_32 = ({ team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1707145818, @@ -16646,6 +16738,7 @@ export const IN_THE_ZONE_32 = ({ team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1707558330, @@ -16744,6 +16837,7 @@ export const IN_THE_ZONE_32 = ({ team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1707586842, @@ -16843,6 +16937,7 @@ export const IN_THE_ZONE_32 = ({ team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1707583597, @@ -16964,6 +17059,7 @@ export const IN_THE_ZONE_32 = ({ team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1707429804, @@ -17073,6 +17169,7 @@ export const IN_THE_ZONE_32 = ({ team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1707539973, @@ -17188,6 +17285,7 @@ export const IN_THE_ZONE_32 = ({ team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1707507831, @@ -17297,6 +17395,7 @@ export const IN_THE_ZONE_32 = ({ team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1707586297, @@ -17403,6 +17502,7 @@ export const IN_THE_ZONE_32 = ({ prefersNotToHost: 1, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1707583885, @@ -17524,6 +17624,7 @@ export const IN_THE_ZONE_32 = ({ team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1707578076, @@ -17636,6 +17737,7 @@ export const IN_THE_ZONE_32 = ({ prefersNotToHost: 1, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1707582953, @@ -17733,6 +17835,7 @@ export const IN_THE_ZONE_32 = ({ team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1707575330, @@ -17849,6 +17952,7 @@ export const IN_THE_ZONE_32 = ({ team: null, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, activeRosterUserIds: [], pickupAvatarUrl: null, createdAt: 1707527645, diff --git a/app/features/tournament-bracket/core/tests/test-utils.ts b/app/features/tournament-bracket/core/tests/test-utils.ts index c48ea09f7..16aa461e1 100644 --- a/app/features/tournament-bracket/core/tests/test-utils.ts +++ b/app/features/tournament-bracket/core/tests/test-utils.ts @@ -4,7 +4,7 @@ import type * as Progression from "../Progression"; import { Tournament } from "../Tournament"; import type { TournamentData } from "../Tournament.server"; -const tournamentCtxTeam = ( +export const tournamentCtxTeam = ( teamId: number, partial?: Partial, ): TournamentData["ctx"]["teams"][0] => { @@ -14,6 +14,7 @@ const tournamentCtxTeam = ( id: teamId, inviteCode: null, avgSeedingSkillOrdinal: null, + startingBracketIdx: null, team: null, mapPool: [], members: [], diff --git a/app/features/tournament-bracket/routes/to.$id.brackets.tsx b/app/features/tournament-bracket/routes/to.$id.brackets.tsx index bcaa99285..68536569b 100644 --- a/app/features/tournament-bracket/routes/to.$id.brackets.tsx +++ b/app/features/tournament-bracket/routes/to.$id.brackets.tsx @@ -413,11 +413,22 @@ export default function TournamentBracketsPage() { return null; }; - const totalTeamsAvailableForTheBracket = () => - bracketIdx === 0 - ? tournament.ctx.teams.length - : (bracket.teamsPendingCheckIn ?? []).length + - bracket.participantTournamentTeamIds.length; + const totalTeamsAvailableForTheBracket = () => { + if (bracket.sources) { + return ( + (bracket.teamsPendingCheckIn ?? []).length + + bracket.participantTournamentTeamIds.length + ); + } + + if (!tournament.isMultiStartingBracket) { + return tournament.ctx.teams.length; + } + + return tournament.ctx.teams.filter( + (team) => (team.startingBracketIdx ?? 0) === bracketIdx, + ).length; + }; return (
diff --git a/app/features/tournament/TournamentRepository.server.ts b/app/features/tournament/TournamentRepository.server.ts index 15c9cb6a2..6ca086d5a 100644 --- a/app/features/tournament/TournamentRepository.server.ts +++ b/app/features/tournament/TournamentRepository.server.ts @@ -171,6 +171,7 @@ export async function findById(id: number) { "TournamentTeam.inviteCode", "TournamentTeam.createdAt", "TournamentTeam.activeRosterUserIds", + "TournamentTeam.startingBracketIdx", "UserSubmittedImage.url as pickupAvatarUrl", jsonArrayFrom( innerEb @@ -686,6 +687,14 @@ export function updateProgression({ allTournamentTeamsOfTournament, ) .execute(); + + await trx + .updateTable("TournamentTeam") + .set({ + startingBracketIdx: null, + }) + .where("tournamentId", "=", tournamentId) + .execute(); } const newSettings: Tables["Tournament"]["settings"] = { diff --git a/app/features/tournament/TournamentTeamRepository.server.ts b/app/features/tournament/TournamentTeamRepository.server.ts index 1cd2b89d4..e48a7af25 100644 --- a/app/features/tournament/TournamentTeamRepository.server.ts +++ b/app/features/tournament/TournamentTeamRepository.server.ts @@ -209,3 +209,31 @@ export function deleteLogo(tournamentTeamId: number) { .where("TournamentTeam.id", "=", tournamentTeamId) .execute(); } + +export function updateStartingBrackets( + startingBrackets: { + tournamentTeamId: number; + startingBracketIdx: number; + }[], +) { + const grouped = Object.groupBy( + startingBrackets, + (sb) => sb.startingBracketIdx, + ); + + return db.transaction().execute(async (trx) => { + for (const [startingBracketIdx, tournamentTeamIds = []] of Object.entries( + grouped, + )) { + await trx + .updateTable("TournamentTeam") + .set({ startingBracketIdx: Number(startingBracketIdx) }) + .where( + "TournamentTeam.id", + "in", + tournamentTeamIds.map((t) => t.tournamentTeamId), + ) + .execute(); + } + }); +} diff --git a/app/features/tournament/routes/to.$id.register.tsx b/app/features/tournament/routes/to.$id.register.tsx index 5c836e702..a6a2c29ed 100644 --- a/app/features/tournament/routes/to.$id.register.tsx +++ b/app/features/tournament/routes/to.$id.register.tsx @@ -40,6 +40,7 @@ import invariant from "~/utils/invariant"; import { LOG_IN_URL, SENDOU_INK_BASE_URL, + SENDOU_INK_DISCORD_URL, navIconUrl, readonlyMapsPage, tournamentJoinPage, @@ -859,7 +860,14 @@ function FriendCode() { {user?.friendCode ? (
- Is the friend code above wrong? Post a message on our Discord helpdesk + Is the friend code above wrong? Post a message on the{" "} + + sendou.ink Discord helpdesk + {" "} to change it.
) : null} diff --git a/app/features/tournament/routes/to.$id.seeds.tsx b/app/features/tournament/routes/to.$id.seeds.tsx index 8fcc31f96..9e5000836 100644 --- a/app/features/tournament/routes/to.$id.seeds.tsx +++ b/app/features/tournament/routes/to.$id.seeds.tsx @@ -22,8 +22,10 @@ import * as React from "react"; import { Alert } from "~/components/Alert"; import { Button } from "~/components/Button"; import { Catcher } from "~/components/Catcher"; +import { Dialog } from "~/components/Dialog"; import { Draggable } from "~/components/Draggable"; import { SubmitButton } from "~/components/SubmitButton"; +import { Table } from "~/components/Table"; import { requireUser } from "~/features/auth/core/user.server"; import { type TournamentDataTeam, @@ -37,6 +39,7 @@ import { tournamentBracketsPage, userResultsPage } from "~/utils/urls"; import { Avatar } from "../../../components/Avatar"; import { InfoPopover } from "../../../components/InfoPopover"; import { ordinalToRoundedSp } from "../../mmr/mmr-utils"; +import * as TournamentTeamRepository from "../TournamentTeamRepository.server"; import { updateTeamSeeds } from "../queries/updateTeamSeeds.server"; import { seedsActionSchema } from "../tournament-schemas.server"; import { tournamentIdFromParams } from "../tournament-utils"; @@ -54,7 +57,30 @@ export const action: ActionFunction = async ({ request, params }) => { validate(tournament.isOrganizer(user)); validate(!tournament.hasStarted, "Tournament has started"); - updateTeamSeeds({ tournamentId, teamIds: data.seeds }); + switch (data._action) { + case "UPDATE_SEEDS": { + updateTeamSeeds({ tournamentId, teamIds: data.seeds }); + break; + } + case "UPDATE_STARTING_BRACKETS": { + const validBracketIdxs = + tournament.ctx.settings.bracketProgression.flatMap( + (bracket, bracketIdx) => (!bracket.sources ? [bracketIdx] : []), + ); + + validate( + data.startingBrackets.every((t) => + validBracketIdxs.includes(t.startingBracketIdx), + ), + "Invalid starting bracket idx", + ); + + await TournamentTeamRepository.updateStartingBrackets( + data.startingBrackets, + ); + break; + } + } clearTournamentDataCache(tournamentId); @@ -149,6 +175,13 @@ export default function TournamentSeedsPage() { )}
+ {tournament.isMultiStartingBracket ? ( + team.startingBracketIdx ?? 0) + .join()} + /> + ) : null}
  • @@ -245,6 +278,118 @@ export default function TournamentSeedsPage() { ); } +function StartingBracketDialog() { + const fetcher = useFetcher(); + const tournament = useTournament(); + + const [isOpen, setIsOpen] = React.useState(false); + const [teamStartingBrackets, setTeamStartingBrackets] = React.useState( + tournament.ctx.teams.map((team) => ({ + tournamentTeamId: team.id, + startingBracketIdx: team.startingBracketIdx ?? 0, + })), + ); + + const startingBrackets = tournament.ctx.settings.bracketProgression + .flatMap((bracket, bracketIdx) => (!bracket.sources ? [bracketIdx] : [])) + .map((bracketIdx) => tournament.bracketByIdx(bracketIdx)!); + + return ( +
    + + setIsOpen(false)} className="w-max"> + +

    Setting starting brackets

    +
    + {startingBrackets.map((bracket) => { + const teamCount = teamStartingBrackets.filter( + (t) => t.startingBracketIdx === bracket.idx, + ).length; + + return ( +
    + {bracket.name} + ({teamCount} teams) +
    + ); + })} +
    + + + + + + + + + + + + + {tournament.ctx.teams.map((team) => { + const { startingBracketIdx } = teamStartingBrackets.find( + ({ tournamentTeamId }) => tournamentTeamId === team.id, + )!; + + return ( + + + + + ); + })} + +
    TeamStarting bracket
    {team.name} + +
    + + Save + +
    +
    +
    + ); +} + function SeedAlert({ teamOrder }: { teamOrder: number[] }) { const tournament = useTournament(); const [teamOrderInDb, setTeamOrderInDb] = React.useState(teamOrder); diff --git a/app/features/tournament/tournament-schemas.server.ts b/app/features/tournament/tournament-schemas.server.ts index 2ade11107..81ae44984 100644 --- a/app/features/tournament/tournament-schemas.server.ts +++ b/app/features/tournament/tournament-schemas.server.ts @@ -8,6 +8,7 @@ import { safeJSONParse, stageId, } from "~/utils/zod"; +import { bracketIdx } from "../tournament-bracket/tournament-bracket-schemas.server"; import { TOURNAMENT } from "./tournament-constants"; export const teamName = z @@ -53,9 +54,24 @@ export const registerSchema = z.union([ }), ]); -export const seedsActionSchema = z.object({ - seeds: z.preprocess(safeJSONParse, z.array(id)), -}); +export const seedsActionSchema = z.union([ + z.object({ + _action: _action("UPDATE_SEEDS"), + seeds: z.preprocess(safeJSONParse, z.array(id)), + }), + z.object({ + _action: _action("UPDATE_STARTING_BRACKETS"), + startingBrackets: z.preprocess( + safeJSONParse, + z.array( + z.object({ + tournamentTeamId: id, + startingBracketIdx: bracketIdx, + }), + ), + ), + }), +]); export const joinSchema = z.object({ trust: z.preprocess(checkboxValueToBoolean, z.boolean()), diff --git a/docs/tournament-creation.md b/docs/tournament-creation.md index d8a2f6d98..2533f8a7e 100644 --- a/docs/tournament-creation.md +++ b/docs/tournament-creation.md @@ -113,6 +113,10 @@ Choose the tournament format. You can have at most 10 brackets with teams advanc Source bracket means a bracket where teams come from. Target bracket means a bracket where teams go to after first playing some other bracket. A bracket can be both at the same time. +### Is follow-up bracket + +If toggled off, teams join from the sign-up. Turns this bracket into a source bracket. You can set which teams start from which bracket in the seeding page. Note that when this option is enabled you are creating a tournament where teams that start in separate brackets will not meet (so in essence they are separate tournaments but just happening on the same tournament page). + ### Placements Placements is a comma separated list of placements. So e.g. the following are valid: @@ -140,6 +144,5 @@ Current limitations. Feel free to leave feedback if it's blocking you from runni - Single-elimination can not be a source bracket - Double-elimination can only be a source bracket when it comes to people who drop in the losers round (negative placements) -- All teams start the tournament in the same bracket - Only one source bracket per target bracket. diff --git a/e2e/tournament-bracket.spec.ts b/e2e/tournament-bracket.spec.ts index 6f2fd9bf4..21fdf10b0 100644 --- a/e2e/tournament-bracket.spec.ts +++ b/e2e/tournament-bracket.spec.ts @@ -492,6 +492,51 @@ test.describe("Tournament bracket", () => { await expect(page.getByTestId("back-to-bracket-button")).toBeVisible(); }); + test("conducts a tournament with many starting brackets", async ({ + page, + }) => { + const tournamentId = 4; + + await seed(page, "SMALL_SOS"); + await impersonate(page); + + await navigate({ + page, + url: tournamentAdminPage(tournamentId), + }); + + await page.getByTestId("edit-event-info-button").click(); + await page.getByTestId("delete-bracket-button").last().click(); + await page.getByTestId("delete-bracket-button").last().click(); + await page.getByTestId("delete-bracket-button").last().click(); + + await page.getByLabel("Is follow-up bracket").click(); + await page.getByLabel("Format").first().selectOption("Single-elimination"); + + await submit(page); + + await page.getByText("Seeds").click(); + await page.getByTestId("set-starting-brackets").click(); + + await page + .getByTestId("starting-bracket-select") + .first() + .selectOption("Great White"); + await page + .getByTestId("starting-bracket-select") + .nth(1) + .selectOption("Great White"); + + await submit(page, "set-starting-brackets-submit-button"); + await page.getByTestId("brackets-tab").click(); + await page.getByText("Great White").click(); + await page.getByTestId("finalize-bracket-button").click(); + await page.getByTestId("confirm-finalize-bracket-button").click(); + + await expect(page.locator('[data-match-id="1"]')).toBeVisible(); + await isNotVisible(page.locator('[data-match-id="2"]')); + }); + test("organizer edits a match after it is done", async ({ page }) => { const tournamentId = 3; diff --git a/migrations/077-starting-bracket-idx.js b/migrations/077-starting-bracket-idx.js new file mode 100644 index 000000000..1257aa998 --- /dev/null +++ b/migrations/077-starting-bracket-idx.js @@ -0,0 +1,7 @@ +export function up(db) { + db.transaction(() => { + db.prepare( + /* sql */ `alter table "TournamentTeam" add "startingBracketIdx" integer`, + ).run(); + })(); +} diff --git a/public/static-assets/img/sq-header/1.avif b/public/static-assets/img/sq-header/1.avif new file mode 100644 index 000000000..8d0656834 Binary files /dev/null and b/public/static-assets/img/sq-header/1.avif differ diff --git a/public/static-assets/img/sq-header/1.png b/public/static-assets/img/sq-header/1.png new file mode 100644 index 000000000..a28f91fac Binary files /dev/null and b/public/static-assets/img/sq-header/1.png differ diff --git a/tsconfig.json b/tsconfig.json index 09ddd911e..54ebb2a01 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,7 @@ { "include": ["./types/env.d.ts", "**/*.ts", "**/*.tsx"], "compilerOptions": { - "lib": ["DOM", "DOM.Iterable", "ES2019"], + "lib": ["DOM", "DOM.Iterable", "es2024"], "module": "ESNext", "isolatedModules": true, "esModuleInterop": true,