mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-03-21 18:04:39 -05:00
Upgrade deps
This commit is contained in:
parent
27f3fbdbce
commit
c43d48f930
|
|
@ -179,7 +179,7 @@ function addAbility({
|
|||
// were given an atRowIndex and atAbilityIndex
|
||||
if (canPlaceAbilityAtSlot(atRowIndex, atAbilityIndex, ability)) {
|
||||
// Assign this ability to the slot
|
||||
abilitiesClone[atRowIndex]![atAbilityIndex] = ability.name;
|
||||
abilitiesClone[atRowIndex][atAbilityIndex] = ability.name;
|
||||
}
|
||||
} else {
|
||||
// Loop through all slots and attempt to place this ability
|
||||
|
|
@ -197,7 +197,7 @@ function addAbility({
|
|||
}
|
||||
|
||||
// Assign this ability to the slot
|
||||
abilitiesClone[rowIndex]![abilityIndex] = ability.name;
|
||||
abilitiesClone[rowIndex][abilityIndex] = ability.name;
|
||||
|
||||
return abilitiesClone;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ export function BuildCard({ build, owner, canEdit = false }: BuildProps) {
|
|||
))}
|
||||
{weapons.length === 1 && (
|
||||
<div className="build__weapon-text">
|
||||
{t(`weapons:MAIN_${weapons[0]!.weaponSplId}` as any)}
|
||||
{t(`weapons:MAIN_${weapons[0].weaponSplId}` as any)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
|
@ -182,7 +182,7 @@ export function BuildCard({ build, owner, canEdit = false }: BuildProps) {
|
|||
<div className="build__bottom-row">
|
||||
<Link
|
||||
to={analyzerPage({
|
||||
weaponId: weapons[0]!.weaponSplId,
|
||||
weaponId: weapons[0].weaponSplId,
|
||||
abilities: abilities.flat(),
|
||||
})}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -1253,9 +1253,9 @@ async function adminBuilds() {
|
|||
ownerId: ADMIN_ID,
|
||||
private: 0,
|
||||
description: Math.random() < 0.75 ? faker.lorem.paragraph() : null,
|
||||
headGearSplId: randomOrderHeadGear[0]!,
|
||||
clothesGearSplId: randomOrderClothesGear[0]!,
|
||||
shoesGearSplId: randomOrderShoesGear[0]!,
|
||||
headGearSplId: randomOrderHeadGear[0],
|
||||
clothesGearSplId: randomOrderClothesGear[0],
|
||||
shoesGearSplId: randomOrderShoesGear[0],
|
||||
weaponSplIds: new Array(
|
||||
faker.helpers.arrayElement([1, 1, 1, 2, 2, 3, 4, 5]),
|
||||
)
|
||||
|
|
@ -1317,9 +1317,9 @@ async function manySplattershotBuilds() {
|
|||
)}`,
|
||||
ownerId,
|
||||
description: Math.random() < 0.75 ? faker.lorem.paragraph() : null,
|
||||
headGearSplId: randomOrderHeadGear[0]!,
|
||||
clothesGearSplId: randomOrderClothesGear[0]!,
|
||||
shoesGearSplId: randomOrderShoesGear[0]!,
|
||||
headGearSplId: randomOrderHeadGear[0],
|
||||
clothesGearSplId: randomOrderClothesGear[0],
|
||||
shoesGearSplId: randomOrderShoesGear[0],
|
||||
weaponSplIds: new Array(
|
||||
faker.helpers.arrayElement([1, 1, 1, 2, 2, 3, 4, 5]),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -15,9 +15,10 @@ import type {
|
|||
import type { GroupSkillDifference, UserSkillDifference } from "./types";
|
||||
import type { ParticipantResult } from "~/modules/brackets-model";
|
||||
|
||||
export type Generated<T> = T extends ColumnType<infer S, infer I, infer U>
|
||||
? ColumnType<S, I | undefined, U>
|
||||
: ColumnType<T, T | undefined, T>;
|
||||
export type Generated<T> =
|
||||
T extends ColumnType<infer S, infer I, infer U>
|
||||
? ColumnType<S, I | undefined, U>
|
||||
: ColumnType<T, T | undefined, T>;
|
||||
|
||||
export interface AllTeam {
|
||||
avatarImgId: number | null;
|
||||
|
|
|
|||
|
|
@ -652,8 +652,8 @@ function subWeaponDefenseDamages(
|
|||
),
|
||||
),
|
||||
],
|
||||
baseValue: secondHalfValues[0]!.baseValue,
|
||||
value: secondHalfValues[0]!.value,
|
||||
baseValue: secondHalfValues[0].baseValue,
|
||||
value: secondHalfValues[0].value,
|
||||
type,
|
||||
},
|
||||
{
|
||||
|
|
@ -667,8 +667,8 @@ function subWeaponDefenseDamages(
|
|||
...firstHalfValues.map((value) => value.distance as number),
|
||||
),
|
||||
],
|
||||
baseValue: firstHalfValues[0]!.baseValue,
|
||||
value: firstHalfValues[0]!.value,
|
||||
baseValue: firstHalfValues[0].baseValue,
|
||||
value: firstHalfValues[0].value,
|
||||
type,
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -92,8 +92,8 @@ PopularBuilds("calculates popular build", () => {
|
|||
]);
|
||||
|
||||
assert.is(builds.length, 1);
|
||||
assert.is(builds[0]!.count, 10);
|
||||
assert.is(builds[0]!.abilities[0]!.ability, "QR");
|
||||
assert.is(builds[0].count, 10);
|
||||
assert.is(builds[0].abilities[0].ability, "QR");
|
||||
});
|
||||
|
||||
PopularBuilds("calculates second most popular build (sorted by count)", () => {
|
||||
|
|
@ -110,7 +110,7 @@ PopularBuilds("calculates second most popular build (sorted by count)", () => {
|
|||
]);
|
||||
|
||||
assert.is(builds.length, 3);
|
||||
assert.is(builds[1]!.abilities[0]!.ability, "SSU");
|
||||
assert.is(builds[1].abilities[0].ability, "SSU");
|
||||
});
|
||||
|
||||
PopularBuilds("sums up abilities", () => {
|
||||
|
|
@ -143,7 +143,7 @@ PopularBuilds("sorts abilities", () => {
|
|||
},
|
||||
]);
|
||||
|
||||
assert.is(builds[0]!.abilities[1]!.ability, "QR");
|
||||
assert.is(builds[0].abilities[1].ability, "QR");
|
||||
});
|
||||
|
||||
AbilityPointCountsToAverages.run();
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ export default function BuildStatsPage() {
|
|||
{data.stats.stackableAbilities.map((stats) => {
|
||||
const apToPx = (ap: number) =>
|
||||
Math.floor(
|
||||
(ap / data.stats.stackableAbilities[0]!.apAverage.weapon) * 200,
|
||||
(ap / data.stats.stackableAbilities[0].apAverage.weapon) * 200,
|
||||
);
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -108,9 +108,9 @@ function dbAbilitiesToArrayOfArrays(
|
|||
invariant(sorted.length === 12, "expected 12 abilities");
|
||||
|
||||
return [
|
||||
[sorted[0]!, sorted[1]!, sorted[2]!, sorted[3]!],
|
||||
[sorted[4]!, sorted[5]!, sorted[6]!, sorted[7]!],
|
||||
[sorted[8]!, sorted[9]!, sorted[10]!, sorted[11]!],
|
||||
[sorted[0], sorted[1], sorted[2], sorted[3]],
|
||||
[sorted[4], sorted[5], sorted[6], sorted[7]],
|
||||
[sorted[8], sorted[9], sorted[10], sorted[11]],
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -280,8 +280,8 @@ function dbAbilitiesToArrayOfArrays(
|
|||
invariant(sorted.length === 12, "expected 12 abilities");
|
||||
|
||||
return [
|
||||
[sorted[0]!, sorted[1]!, sorted[2]!, sorted[3]!],
|
||||
[sorted[4]!, sorted[5]!, sorted[6]!, sorted[7]!],
|
||||
[sorted[8]!, sorted[9]!, sorted[10]!, sorted[11]!],
|
||||
[sorted[0], sorted[1], sorted[2], sorted[3]],
|
||||
[sorted[4], sorted[5], sorted[6], sorted[7]],
|
||||
[sorted[8], sorted[9], sorted[10], sorted[11]],
|
||||
];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,25 +107,24 @@ export const shouldRevalidate: ShouldRevalidateFunction = (args) => {
|
|||
}
|
||||
// all meaningful filters identical -> skip revalidation
|
||||
if (
|
||||
newFilters?.every(
|
||||
(f1) =>
|
||||
oldFilters?.some((f2) => {
|
||||
if (f1.type !== f2.type) return false;
|
||||
newFilters?.every((f1) =>
|
||||
oldFilters?.some((f2) => {
|
||||
if (f1.type !== f2.type) return false;
|
||||
|
||||
if (f1.type === "mode" && f2.type === "mode") {
|
||||
return f1.mode === f2.mode;
|
||||
}
|
||||
if (f1.type === "date" && f2.type === "date") {
|
||||
return f1.date === f2.date;
|
||||
}
|
||||
if (f1.type !== "ability" || f2.type !== "ability") return false;
|
||||
if (f1.type === "mode" && f2.type === "mode") {
|
||||
return f1.mode === f2.mode;
|
||||
}
|
||||
if (f1.type === "date" && f2.type === "date") {
|
||||
return f1.date === f2.date;
|
||||
}
|
||||
if (f1.type !== "ability" || f2.type !== "ability") return false;
|
||||
|
||||
return (
|
||||
f1.ability === f2.ability &&
|
||||
f1.comparison === f2.comparison &&
|
||||
f1.value === f2.value
|
||||
);
|
||||
}),
|
||||
return (
|
||||
f1.ability === f2.ability &&
|
||||
f1.comparison === f2.comparison &&
|
||||
f1.value === f2.value
|
||||
);
|
||||
}),
|
||||
)
|
||||
) {
|
||||
return false;
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ export const action: ActionFunction = async ({ params, request }) => {
|
|||
canDeleteCalendarEvent({
|
||||
user,
|
||||
event,
|
||||
startTime: databaseTimestampToDate(event.startTimes[0]!),
|
||||
startTime: databaseTimestampToDate(event.startTimes[0]),
|
||||
}),
|
||||
);
|
||||
|
||||
|
|
@ -233,7 +233,7 @@ export default function CalendarEventPage() {
|
|||
<Description />
|
||||
{canDeleteCalendarEvent({
|
||||
user,
|
||||
startTime: databaseTimestampToDate(data.event.startTimes[0]!),
|
||||
startTime: databaseTimestampToDate(data.event.startTimes[0]),
|
||||
event: data.event,
|
||||
}) ? (
|
||||
<FormWithConfirm
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ export function generateMapList(
|
|||
for (let i = 0; i < games.length; i++) {
|
||||
const roundMapList: ModeWithStage[] = [];
|
||||
|
||||
for (let j = 0; j < games[i]!; j++) {
|
||||
for (let j = 0; j < games[i]; j++) {
|
||||
const mode = modeList[modeIndex];
|
||||
invariant(mode, "Mode is missing");
|
||||
|
||||
|
|
|
|||
|
|
@ -123,7 +123,7 @@ export class MapPool {
|
|||
var data = this.stageModePairs;
|
||||
|
||||
return {
|
||||
next: () => ({ value: data[++index]!, done: !(index in data) }),
|
||||
next: () => ({ value: data[++index], done: !(index in data) }),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -105,8 +105,9 @@ CalculateDamage("BRU increases Splash Wall hitpoints", () => {
|
|||
abilityPoints: new Map([["BRU", 10]]),
|
||||
});
|
||||
|
||||
const hpWithoutBRU = withoutBRU.find((d) => d.receiver === "Wsb_Shield")
|
||||
?.hitPoints;
|
||||
const hpWithoutBRU = withoutBRU.find(
|
||||
(d) => d.receiver === "Wsb_Shield",
|
||||
)?.hitPoints;
|
||||
const hpWithBRU = withBRU.find((d) => d.receiver === "Wsb_Shield")?.hitPoints;
|
||||
|
||||
assert.ok(typeof hpWithoutBRU === "number");
|
||||
|
|
@ -123,8 +124,9 @@ CalculateDamage("SPU increases Big Bubbler hitpoints", () => {
|
|||
const hpWithoutSPU = withoutSPU.find(
|
||||
(d) => d.receiver === "GreatBarrier_Barrier",
|
||||
)?.hitPoints;
|
||||
const hpWithSPU = withSPU.find((d) => d.receiver === "GreatBarrier_Barrier")
|
||||
?.hitPoints;
|
||||
const hpWithSPU = withSPU.find(
|
||||
(d) => d.receiver === "GreatBarrier_Barrier",
|
||||
)?.hitPoints;
|
||||
|
||||
assert.ok(typeof hpWithoutSPU === "number");
|
||||
assert.ok(typeof hpWithSPU === "number");
|
||||
|
|
|
|||
|
|
@ -271,7 +271,7 @@ export function calculateDamage({
|
|||
return damage.value;
|
||||
};
|
||||
const baseMultiplier = () => {
|
||||
const normalMultiplier = multipliers[damage.type]![receiver];
|
||||
const normalMultiplier = multipliers[damage.type][receiver];
|
||||
if (toCombine) {
|
||||
const actualDamage = () => {
|
||||
if (toCombine.multiplierOnly) {
|
||||
|
|
@ -283,7 +283,7 @@ export function calculateDamage({
|
|||
};
|
||||
|
||||
const otherMultiplier =
|
||||
multipliers[toCombine.combineWith]![receiver];
|
||||
multipliers[toCombine.combineWith][receiver];
|
||||
|
||||
// calculate "made up" multiplier that is taking the
|
||||
// weighted average of the two multipliers
|
||||
|
|
|
|||
|
|
@ -85,11 +85,13 @@ export function addReplayIndicator({
|
|||
}): DividedGroupsUncensored {
|
||||
if (!recentMatchPlayers.length) return groups;
|
||||
|
||||
const ownGroupId = recentMatchPlayers.find((u) => u.userId === userId)
|
||||
?.groupId;
|
||||
const ownGroupId = recentMatchPlayers.find(
|
||||
(u) => u.userId === userId,
|
||||
)?.groupId;
|
||||
invariant(ownGroupId, "own group not found");
|
||||
const otherGroupId = recentMatchPlayers.find((u) => u.groupId !== ownGroupId)
|
||||
?.groupId;
|
||||
const otherGroupId = recentMatchPlayers.find(
|
||||
(u) => u.groupId !== ownGroupId,
|
||||
)?.groupId;
|
||||
invariant(otherGroupId, "other group not found");
|
||||
|
||||
const opponentPlayers = recentMatchPlayers
|
||||
|
|
|
|||
|
|
@ -233,7 +233,7 @@ export default function TeamSearchPage() {
|
|||
</div>
|
||||
<div className="team-search__team__members">
|
||||
{team.members.length === 1
|
||||
? team.members[0]!.discordName
|
||||
? team.members[0].discordName
|
||||
: joinListToNaturalString(
|
||||
team.members.map((member) => member.discordName),
|
||||
"&",
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ export const handle: SendouRouteHandle = {
|
|||
|
||||
if (!data) return [];
|
||||
|
||||
const firstName = data.placements[0]!.name;
|
||||
const firstName = data.placements[0].name;
|
||||
|
||||
return [
|
||||
{
|
||||
|
|
@ -38,7 +38,7 @@ export const handle: SendouRouteHandle = {
|
|||
{
|
||||
text: firstName,
|
||||
type: "TEXT",
|
||||
href: topSearchPlayerPage(data.placements[0]!.playerId),
|
||||
href: topSearchPlayerPage(data.placements[0].playerId),
|
||||
},
|
||||
];
|
||||
},
|
||||
|
|
@ -57,7 +57,7 @@ export const meta: MetaFunction = (args) => {
|
|||
{ title: data.title },
|
||||
{
|
||||
name: "description",
|
||||
content: `Splatoon 3 X Battle for the player ${data.placements[0]!.name}`,
|
||||
content: `Splatoon 3 X Battle for the player ${data.placements[0].name}`,
|
||||
},
|
||||
];
|
||||
};
|
||||
|
|
@ -71,7 +71,7 @@ export const loader = async ({ params, request }: LoaderFunctionArgs) => {
|
|||
|
||||
return {
|
||||
placements,
|
||||
title: makeTitle([placements[0]!.name, t("pages.xsearch")]),
|
||||
title: makeTitle([placements[0].name, t("pages.xsearch")]),
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -79,21 +79,21 @@ export default function XSearchPlayerPage() {
|
|||
const { t } = useTranslation(["common"]);
|
||||
const data = useLoaderData<typeof loader>();
|
||||
|
||||
const firstName = data.placements[0]!.name;
|
||||
const firstName = data.placements[0].name;
|
||||
const aliases = removeDuplicates(
|
||||
data.placements
|
||||
.map((placement) => placement.name)
|
||||
.filter((name) => name !== firstName),
|
||||
);
|
||||
|
||||
const hasUserLinked = Boolean(data.placements[0]!.discordId);
|
||||
const hasUserLinked = Boolean(data.placements[0].discordId);
|
||||
|
||||
return (
|
||||
<Main halfWidth className="stack lg">
|
||||
<div>
|
||||
<h2 className="text-lg">
|
||||
{hasUserLinked ? (
|
||||
<Link to={userPage(data.placements[0]!)}>{firstName}</Link>
|
||||
<Link to={userPage(data.placements[0])}>{firstName}</Link>
|
||||
) : (
|
||||
<>{firstName}</>
|
||||
)}{" "}
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ export const meta: MetaFunction = (args) => {
|
|||
|
||||
export const loader = async ({ request }: LoaderFunctionArgs) => {
|
||||
const availableMonthYears = monthYears();
|
||||
const { month: latestMonth, year: latestYear } = availableMonthYears[0]!;
|
||||
const { month: latestMonth, year: latestYear } = availableMonthYears[0];
|
||||
|
||||
// #region parse URL params
|
||||
const url = new URL(request.url);
|
||||
|
|
@ -128,8 +128,8 @@ export default function XSearchPage() {
|
|||
};
|
||||
|
||||
const selectValue = `${
|
||||
searchParams.get("month") ?? data.availableMonthYears[0]!.month
|
||||
}-${searchParams.get("year") ?? data.availableMonthYears[0]!.year}-${
|
||||
searchParams.get("month") ?? data.availableMonthYears[0].month
|
||||
}-${searchParams.get("year") ?? data.availableMonthYears[0].year}-${
|
||||
searchParams.get("mode") ?? "SZ"
|
||||
}-${searchParams.get("region") ?? "WEST"}`;
|
||||
|
||||
|
|
@ -143,8 +143,8 @@ export default function XSearchPage() {
|
|||
>
|
||||
{selectOptions(data.availableMonthYears).map((group) => (
|
||||
<optgroup
|
||||
key={group[0]!.id}
|
||||
label={t(`common:divisions.${group[0]!.region}`)}
|
||||
key={group[0].id}
|
||||
label={t(`common:divisions.${group[0].region}`)}
|
||||
>
|
||||
{group.map((option) => (
|
||||
<option
|
||||
|
|
|
|||
|
|
@ -282,10 +282,10 @@ function ModeProgressIndicator({
|
|||
i <= maxIndexThatWillBePlayedForSure,
|
||||
"tournament-bracket__mode-progress__image__team-one-win":
|
||||
data.results[i] &&
|
||||
data.results[i]!.winnerTeamId === data.match.opponentOne?.id,
|
||||
data.results[i].winnerTeamId === data.match.opponentOne?.id,
|
||||
"tournament-bracket__mode-progress__image__team-two-win":
|
||||
data.results[i] &&
|
||||
data.results[i]!.winnerTeamId === data.match.opponentTwo?.id,
|
||||
data.results[i].winnerTeamId === data.match.opponentTwo?.id,
|
||||
"tournament-bracket__mode-progress__image__selected":
|
||||
i === selectedResultIndex,
|
||||
"cursor-pointer": Boolean(setSelectedResultIndex),
|
||||
|
|
|
|||
|
|
@ -120,17 +120,17 @@ export function TeamRosterInputs({
|
|||
</div>
|
||||
<TeamRosterInputsCheckboxes
|
||||
teamId={team.id}
|
||||
checkedPlayers={result?.participantIds ?? checkedPlayers[teamI]!}
|
||||
checkedPlayers={result?.participantIds ?? checkedPlayers[teamI]}
|
||||
presentational={presentational}
|
||||
handlePlayerClick={(playerId: number) => {
|
||||
const newCheckedPlayers = () => {
|
||||
const newPlayers = clone(checkedPlayers);
|
||||
if (checkedPlayers.flat().includes(playerId)) {
|
||||
newPlayers[teamI] = newPlayers[teamI]!.filter(
|
||||
newPlayers[teamI] = newPlayers[teamI].filter(
|
||||
(id) => id !== playerId,
|
||||
);
|
||||
} else {
|
||||
newPlayers[teamI]!.push(playerId);
|
||||
newPlayers[teamI].push(playerId);
|
||||
}
|
||||
|
||||
return newPlayers;
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ export function resolveBestOfs(
|
|||
|
||||
// special case: only 2 teams
|
||||
if (matches.length === 1) {
|
||||
result.push([7, matches[0]!.matchId]);
|
||||
result.push([7, matches[0].matchId]);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -34,8 +34,8 @@ export function resolveBestOfs(
|
|||
const finalsMatches = matches.filter((match) => match.groupNumber === 3);
|
||||
|
||||
invariant(finalsMatches.length === 2, "finalsMatches must be 2");
|
||||
result.push([5, finalsMatches[0]!.matchId]);
|
||||
result.push([5, finalsMatches[1]!.matchId]);
|
||||
result.push([5, finalsMatches[0].matchId]);
|
||||
result.push([5, finalsMatches[1].matchId]);
|
||||
|
||||
/// Best of 5
|
||||
|
||||
|
|
@ -68,7 +68,7 @@ export function resolveBestOfs(
|
|||
);
|
||||
invariant(losersFinals.length === 1, "losersFinals must be 1");
|
||||
|
||||
result.push([5, losersFinals[0]!.matchId]);
|
||||
result.push([5, losersFinals[0].matchId]);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,8 +84,9 @@ export const action: ActionFunction = async ({ request, params }) => {
|
|||
tournamentId,
|
||||
});
|
||||
if (data.trust) {
|
||||
const inviterUserId = teamToJoin.members.find((member) => member.isOwner)
|
||||
?.userId;
|
||||
const inviterUserId = teamToJoin.members.find(
|
||||
(member) => member.isOwner,
|
||||
)?.userId;
|
||||
invariant(inviterUserId, "Inviter user could not be resolved");
|
||||
giveTrust({
|
||||
trustGiverUserId: user.id,
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ export function isOneModeTournamentOf(
|
|||
tournament: Pick<Tournament, "mapPickingStyle">,
|
||||
) {
|
||||
return modesIncluded(tournament).length === 1
|
||||
? modesIncluded(tournament)[0]!
|
||||
? modesIncluded(tournament)[0]
|
||||
: null;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -273,7 +273,7 @@ function BadgeContainer(props: { badges: UserPageLoaderData["badges"] }) {
|
|||
setBadges(
|
||||
badges.map((b, i) => {
|
||||
if (i === 0) return badge;
|
||||
if (b.code === badge.code) return badges[0]!;
|
||||
if (b.code === badge.code) return badges[0];
|
||||
|
||||
return b;
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ function Match({
|
|||
}) {
|
||||
const { t } = useTranslation(["game-misc", "weapons"]);
|
||||
|
||||
const weapon = match.weapons.length === 1 ? match.weapons[0]! : null;
|
||||
const weapon = match.weapons.length === 1 ? match.weapons[0] : null;
|
||||
const weapons = match.weapons.length === 8 ? match.weapons : null;
|
||||
|
||||
return (
|
||||
|
|
|
|||
|
|
@ -342,7 +342,7 @@ function extractYoutubeIdFromVideoUrl(url: string): string {
|
|||
const found = match?.[1];
|
||||
if (!found) return "";
|
||||
|
||||
const withoutSearchParams = found.split("&")[0]!;
|
||||
const withoutSearchParams = found.split("&")[0];
|
||||
|
||||
return withoutSearchParams;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -516,11 +516,11 @@ export function byeWinner(opponents: Duel): ParticipantSlot {
|
|||
|
||||
if (opponents[0] === null && opponents[1] !== null)
|
||||
// opponent1 BYE.
|
||||
return { id: opponents[1]!.id }; // opponent2.
|
||||
return { id: opponents[1].id }; // opponent2.
|
||||
|
||||
if (opponents[0] !== null && opponents[1] === null)
|
||||
// opponent2 BYE.
|
||||
return { id: opponents[0]!.id }; // opponent1.
|
||||
return { id: opponents[0].id }; // opponent1.
|
||||
|
||||
return { id: null }; // Normal.
|
||||
}
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ TournamentMapListGenerator("Modes are spread evenly", () => {
|
|||
const rankedMode = mode as RankedModeShort;
|
||||
if (!modes.has(rankedMode)) {
|
||||
assert.equal(i, 4, "Repeated mode early");
|
||||
assert.equal(mode, mapList[0]!.mode, "1st and 5th mode are not the same");
|
||||
assert.equal(mode, mapList[0].mode, "1st and 5th mode are not the same");
|
||||
}
|
||||
|
||||
modes.delete(rankedMode);
|
||||
|
|
@ -145,8 +145,8 @@ TournamentMapListGenerator(
|
|||
assert.equal(mapList1.length, 5);
|
||||
|
||||
for (let i = 0; i < mapList1.length; i++) {
|
||||
assert.equal(mapList1[i]!.stageId, mapList2[i]!.stageId);
|
||||
assert.equal(mapList1[i]!.mode, mapList2[i]!.mode);
|
||||
assert.equal(mapList1[i].stageId, mapList2[i].stageId);
|
||||
assert.equal(mapList1[i].mode, mapList2[i].mode);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
@ -171,8 +171,8 @@ TournamentMapListGenerator(
|
|||
assert.equal(mapList1.length, 5);
|
||||
|
||||
for (let i = 0; i < mapList1.length; i++) {
|
||||
assert.equal(mapList1[i]!.stageId, mapList2[i]!.stageId);
|
||||
assert.equal(mapList1[i]!.mode, mapList2[i]!.mode);
|
||||
assert.equal(mapList1[i].stageId, mapList2[i].stageId);
|
||||
assert.equal(mapList1[i].mode, mapList2[i].mode);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
@ -208,8 +208,8 @@ TournamentMapListGenerator(
|
|||
assert.equal(mapList1.length, 5);
|
||||
|
||||
for (let i = 0; i < mapList1.length; i++) {
|
||||
assert.equal(mapList1[i]!.stageId, mapList2[i]!.stageId);
|
||||
assert.equal(mapList1[i]!.mode, mapList2[i]!.mode);
|
||||
assert.equal(mapList1[i].stageId, mapList2[i].stageId);
|
||||
assert.equal(mapList1[i].mode, mapList2[i].mode);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
@ -303,7 +303,7 @@ TournamentMapListGenerator("Handles worst case with duplication", () => {
|
|||
|
||||
// no consecutive stage replays
|
||||
for (let i = 0; i < maplist.length - 1; i++) {
|
||||
assert.not.equal(maplist[i]!.stageId, maplist[i + 1]!.stageId);
|
||||
assert.not.equal(maplist[i].stageId, maplist[i + 1].stageId);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -368,8 +368,8 @@ TournamentMapListGenerator("No map picked by same team twice in row", () => {
|
|||
});
|
||||
|
||||
for (let j = 0; j < mapList.length - 1; j++) {
|
||||
if (typeof mapList[j]!.source !== "number") continue;
|
||||
assert.not.equal(mapList[j]!.source, mapList[j + 1]!.source);
|
||||
if (typeof mapList[j].source !== "number") continue;
|
||||
assert.not.equal(mapList[j].source, mapList[j + 1].source);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
@ -639,7 +639,7 @@ TournamentMapListGeneratorOneMode(
|
|||
tiebreakerMaps: new MapPool([]),
|
||||
});
|
||||
for (let i = 0; i < mapList.length - 1; i++) {
|
||||
assert.equal(mapList[i]!.mode, "SZ");
|
||||
assert.equal(mapList[i].mode, "SZ");
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
@ -662,7 +662,7 @@ TournamentMapListGeneratorOneMode(
|
|||
tiebreakerMaps: new MapPool([]),
|
||||
});
|
||||
for (let i = 0; i < mapList.length - 1; i++) {
|
||||
assert.equal(mapList[i]!.mode, "SZ");
|
||||
assert.equal(mapList[i].mode, "SZ");
|
||||
}
|
||||
},
|
||||
);
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ export function createTournamentMapList(
|
|||
)
|
||||
.map((stageId) => ({
|
||||
stageId,
|
||||
mode: input.modesIncluded[0]!,
|
||||
mode: input.modesIncluded[0],
|
||||
score: 0,
|
||||
source: "TIEBREAKER" as const,
|
||||
}));
|
||||
|
|
@ -200,7 +200,7 @@ export function createTournamentMapList(
|
|||
|
||||
function getDefaultMapPool() {
|
||||
if (tournamentIsOneModeOnly()) {
|
||||
const mode = input.modesIncluded[0]!;
|
||||
const mode = input.modesIncluded[0];
|
||||
|
||||
return stageIds.map((id) => ({ mode, stageId: id }));
|
||||
}
|
||||
|
|
@ -266,17 +266,17 @@ export function createTournamentMapList(
|
|||
|
||||
let previousModeShouldBe: ModeShort | undefined;
|
||||
for (let i = 0; i < mapList.length; i++) {
|
||||
if (mapList[i]!.mode === stage.mode) {
|
||||
if (mapList[i].mode === stage.mode) {
|
||||
if (i === 0) {
|
||||
previousModeShouldBe = mapList[mapList.length - 1]!.mode;
|
||||
previousModeShouldBe = mapList[mapList.length - 1].mode;
|
||||
} else {
|
||||
previousModeShouldBe = mapList[i - 1]!.mode;
|
||||
previousModeShouldBe = mapList[i - 1].mode;
|
||||
}
|
||||
}
|
||||
}
|
||||
invariant(previousModeShouldBe, "Couldn't resolve maplist pattern");
|
||||
|
||||
return mapList[mapList.length - 1]!.mode !== previousModeShouldBe;
|
||||
return mapList[mapList.length - 1].mode !== previousModeShouldBe;
|
||||
}
|
||||
|
||||
function isNotFollowingModeOrder(stage: StageValidatorInput) {
|
||||
|
|
@ -375,7 +375,7 @@ export function createTournamentMapList(
|
|||
if (!tournamentIsOneModeOnly()) return true;
|
||||
|
||||
// specifically made tiebreaker map is considered good
|
||||
const last = mapList[mapList.length - 1]!;
|
||||
const last = mapList[mapList.length - 1];
|
||||
if (last.source === "TIEBREAKER") return true;
|
||||
|
||||
// we can't have a map from pools of both teams if both didn't submit maps
|
||||
|
|
@ -383,7 +383,7 @@ export function createTournamentMapList(
|
|||
return true;
|
||||
}
|
||||
|
||||
const tieBreakerMap = mapList[mapList.length - 1]!;
|
||||
const tieBreakerMap = mapList[mapList.length - 1];
|
||||
|
||||
let appearanceCount = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ function mulberry32(a: number) {
|
|||
}
|
||||
|
||||
export const seededRandom = (seed: string) => {
|
||||
const rng = mulberry32(cyrb128(seed)[0]!);
|
||||
const rng = mulberry32(cyrb128(seed)[0]);
|
||||
|
||||
const rnd = (lo: number, hi?: number, defaultHi = 1) => {
|
||||
if (hi === undefined) {
|
||||
|
|
|
|||
3498
package-lock.json
generated
3498
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
56
package.json
56
package.json
|
|
@ -52,40 +52,40 @@
|
|||
"cf:noe2e": "npm run test:unit && npm run check-translation-jsons && npm run lint:css -- --fix && npm run lint:ts -- --fix && npm run prettier:write && npm run typecheck"
|
||||
},
|
||||
"dependencies": {
|
||||
"@aws-sdk/client-s3": "^3.485.0",
|
||||
"@aws-sdk/lib-storage": "^3.485.0",
|
||||
"@aws-sdk/client-s3": "^3.504.0",
|
||||
"@aws-sdk/lib-storage": "^3.504.0",
|
||||
"@dnd-kit/core": "^6.1.0",
|
||||
"@dnd-kit/sortable": "^8.0.0",
|
||||
"@dnd-kit/utilities": "^3.2.2",
|
||||
"@epic-web/cachified": "^4.0.0",
|
||||
"@faker-js/faker": "^8.3.1",
|
||||
"@headlessui/react": "^1.7.17",
|
||||
"@faker-js/faker": "^8.4.0",
|
||||
"@headlessui/react": "^1.7.18",
|
||||
"@popperjs/core": "^2.11.8",
|
||||
"@remix-run/node": "^2.4.1",
|
||||
"@remix-run/react": "^2.4.1",
|
||||
"@remix-run/serve": "^2.4.1",
|
||||
"@remix-run/node": "^2.6.0",
|
||||
"@remix-run/react": "^2.6.0",
|
||||
"@remix-run/serve": "^2.6.0",
|
||||
"@tldraw/tldraw": "^1.29.2",
|
||||
"aws-sdk": "^2.1531.0",
|
||||
"better-sqlite3": "^9.2.2",
|
||||
"aws-sdk": "^2.1550.0",
|
||||
"better-sqlite3": "^9.4.0",
|
||||
"clsx": "^2.1.0",
|
||||
"compressorjs": "^1.2.1",
|
||||
"countries-list": "^3.0.6",
|
||||
"date-fns": "^3.1.0",
|
||||
"date-fns": "^3.3.1",
|
||||
"fuse.js": "^7.0.0",
|
||||
"gray-matter": "^4.0.3",
|
||||
"i18next": "^23.7.16",
|
||||
"i18next": "^23.8.2",
|
||||
"i18next-browser-languagedetector": "^7.2.0",
|
||||
"i18next-fs-backend": "^2.3.1",
|
||||
"i18next-http-backend": "^2.4.2",
|
||||
"isbot": "^4.3.0",
|
||||
"i18next-http-backend": "^2.4.3",
|
||||
"isbot": "^4.4.0",
|
||||
"just-capitalize": "^3.2.0",
|
||||
"just-clone": "^6.2.0",
|
||||
"just-random-integer": "^4.2.0",
|
||||
"just-shuffle": "^4.2.0",
|
||||
"kysely": "^0.27.2",
|
||||
"lru-cache": "10.1.0",
|
||||
"markdown-to-jsx": "^7.4.0",
|
||||
"nanoid": "~5.0.4",
|
||||
"lru-cache": "10.2.0",
|
||||
"markdown-to-jsx": "^7.4.1",
|
||||
"nanoid": "~5.0.5",
|
||||
"node-cron": "3.0.3",
|
||||
"nprogress": "^0.2.0",
|
||||
"openskill": "^3.1.0",
|
||||
|
|
@ -93,10 +93,10 @@
|
|||
"react-charts": "^3.0.0-beta.57",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-flip-toolkit": "^7.1.0",
|
||||
"react-i18next": "^14.0.0",
|
||||
"react-i18next": "^14.0.1",
|
||||
"react-popper": "^2.3.0",
|
||||
"react-responsive-masonry": "^2.1.7",
|
||||
"react-use": "^17.4.2",
|
||||
"react-use": "^17.5.0",
|
||||
"reconnecting-websocket": "^4.4.0",
|
||||
"remix-auth": "^3.6.0",
|
||||
"remix-auth-oauth2": "^1.11.1",
|
||||
|
|
@ -108,29 +108,29 @@
|
|||
"zod": "^3.22.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "^1.40.1",
|
||||
"@remix-run/dev": "^2.4.1",
|
||||
"@swc-node/register": "^1.6.8",
|
||||
"@types/better-sqlite3": "7.6.8",
|
||||
"@playwright/test": "^1.41.2",
|
||||
"@remix-run/dev": "^2.6.0",
|
||||
"@swc-node/register": "^1.8.0",
|
||||
"@types/better-sqlite3": "7.6.9",
|
||||
"@types/i18next-fs-backend": "^1.1.5",
|
||||
"@types/node-cron": "^3.0.11",
|
||||
"@types/nprogress": "^0.2.3",
|
||||
"@types/prettier": "3.0.0",
|
||||
"@types/react": "^18.2.47",
|
||||
"@types/react": "^18.2.52",
|
||||
"@types/react-dom": "^18.2.18",
|
||||
"@types/react-responsive-masonry": "^2.1.3",
|
||||
"@typescript-eslint/eslint-plugin": "^6.18.0",
|
||||
"@typescript-eslint/parser": "^6.18.0",
|
||||
"@typescript-eslint/eslint-plugin": "^6.20.0",
|
||||
"@typescript-eslint/parser": "^6.20.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"dotenv": "^16.3.1",
|
||||
"dotenv": "^16.4.1",
|
||||
"eslint": "^8.56.0",
|
||||
"eslint-plugin-react": "^7.33.2",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"ignore-styles": "^5.0.1",
|
||||
"ley": "^0.8.1",
|
||||
"mockdate": "^3.0.5",
|
||||
"prettier": "3.1.1",
|
||||
"stylelint": "^16.1.0",
|
||||
"prettier": "3.2.4",
|
||||
"stylelint": "^16.2.1",
|
||||
"stylelint-config-standard": "^36.0.0",
|
||||
"tsconfig-paths": "^4.2.0",
|
||||
"tsm": "^2.3.0",
|
||||
|
|
|
|||
|
|
@ -95,12 +95,12 @@ for (const file of fileNames) {
|
|||
throw new Error(`missing keys in ${lang}/${file}`);
|
||||
}
|
||||
} else {
|
||||
missingTranslations[lang]![key] = missingKeys;
|
||||
missingTranslations[lang][key] = missingKeys;
|
||||
}
|
||||
} catch (e) {
|
||||
if ((e as { code: string }).code !== "ENOENT") throw e;
|
||||
|
||||
missingTranslations[lang]![key] = englishContentKeys;
|
||||
missingTranslations[lang][key] = englishContentKeys;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -323,7 +323,7 @@ function MDOverviewTable({
|
|||
|
||||
cells.push(
|
||||
MDCompletionStatus({
|
||||
totalCount: totalTranslationCounts[fileKey]!,
|
||||
totalCount: totalTranslationCounts[fileKey],
|
||||
missingCount: missingKeysInFile.length,
|
||||
}),
|
||||
);
|
||||
|
|
@ -364,8 +364,7 @@ function MDMissingKeysList({
|
|||
const checkbox = noneMissing ? MD.ticked : MD.unticked;
|
||||
const fileEntry = checkbox(MD.inlineCode(`${fileKey}.json`));
|
||||
|
||||
const allMissing =
|
||||
missingKeys.length === totalTranslationCounts[fileKey]!;
|
||||
const allMissing = missingKeys.length === totalTranslationCounts[fileKey];
|
||||
|
||||
const keysLabel = allMissing
|
||||
? "All keys"
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
"strict": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"~/*": ["./app/*"]
|
||||
"~/*": ["./app/*"],
|
||||
},
|
||||
"noEmit": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
|
|
@ -24,9 +24,9 @@
|
|||
"noFallthroughCasesInSwitch": true,
|
||||
"noPropertyAccessFromIndexSignature": true,
|
||||
"useUnknownInCatchVariables": true,
|
||||
"skipLibCheck": true
|
||||
"skipLibCheck": true,
|
||||
},
|
||||
"ts-node": {
|
||||
"transpileOnly": true
|
||||
}
|
||||
"transpileOnly": true,
|
||||
},
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user