{ "version": 3, "sources": ["../../../server/tournaments/index.ts"], "sourcesContent": ["import { Elimination } from './generator-elimination';\nimport { RoundRobin } from './generator-round-robin';\nimport { Utils } from '../../lib';\nimport { PRNG } from '../../sim/prng';\nimport type { BestOfGame } from '../room-battle-bestof';\n\nexport interface TournamentRoomSettings {\n\tallowModjoin?: boolean;\n\tallowScouting?: boolean;\n\tannouncements?: boolean;\n\tautoconfirmedOnly?: boolean;\n\tautodq?: number;\n\tautostart?: number | boolean;\n\tforcePublic?: boolean;\n\tforceTimer?: boolean;\n\tplayerCap?: number;\n\trecentToursLength?: number;\n\trecentTours?: { name: string, baseFormat: string, time: number }[];\n\tblockRecents?: boolean;\n}\n\ntype Generator = RoundRobin | Elimination;\n\nconst BRACKET_MINIMUM_UPDATE_INTERVAL = 2 * 1000;\nconst AUTO_DISQUALIFY_WARNING_TIMEOUT = 30 * 1000;\nconst MAX_AUTO_DISQUALIFY_TIMEOUT = 60 * 60 * 1000;\nconst AUTO_START_MINIMUM_TIMEOUT = 30 * 1000;\nconst MAX_REASON_LENGTH = 300;\nconst MAX_CUSTOM_NAME_LENGTH = 100;\nconst TOURBAN_DURATION = 14 * 24 * 60 * 60 * 1000;\n\nPunishments.addRoomPunishmentType({\n\ttype: 'TOURBAN',\n\tdesc: 'banned from tournaments',\n});\n\nconst TournamentGenerators = {\n\t__proto__: null,\n\troundrobin: RoundRobin,\n\telimination: Elimination,\n};\n\nfunction usersToNames(users: TournamentPlayer[]) {\n\treturn users.map(user => user.name);\n}\n\nexport class TournamentPlayer extends Rooms.RoomGamePlayer {\n\treadonly availableMatches: Set;\n\tisBusy: boolean;\n\tinProgressMatch: { to: TournamentPlayer, room: GameRoom } | null;\n\tpendingChallenge: {\n\t\tfrom?: TournamentPlayer,\n\t\tto?: TournamentPlayer,\n\t\tteam: string,\n\t\thidden: boolean,\n\t\tinviteOnly: boolean,\n\t} | null;\n\tisDisqualified: boolean;\n\tisEliminated: boolean;\n\tautoDisqualifyWarned: boolean;\n\tlastActionTime: number;\n\twins: number;\n\tlosses: number;\n\tgames: number;\n\tscore: number;\n\tconstructor(user: User | string | null, game: Tournament, num: number) {\n\t\tsuper(user, game, num);\n\t\tthis.availableMatches = new Set();\n\t\tthis.isBusy = false;\n\t\tthis.inProgressMatch = null;\n\t\tthis.pendingChallenge = null;\n\t\tthis.isDisqualified = false;\n\t\tthis.isEliminated = false;\n\t\tthis.autoDisqualifyWarned = false;\n\t\tthis.lastActionTime = 0;\n\n\t\tthis.wins = 0;\n\t\tthis.losses = 0;\n\t\tthis.games = 0;\n\t\tthis.score = 0;\n\t}\n}\n\nexport class Tournament extends Rooms.RoomGame {\n\toverride readonly gameid = 'tournament' as ID;\n\treadonly isTournament: true;\n\treadonly completedMatches: Set;\n\t/** Format ID not including custom rules */\n\treadonly baseFormat: ID;\n\t/**\n\t * Full format specifier, including custom rules (such as 'gen7challengecup1v1@@@speciesclause')\n\t */\n\tfullFormat: string;\n\tname: string;\n\tcustomRules: string[];\n\tgenerator: Generator;\n\tisRated: boolean;\n\tallowScouting: boolean;\n\tallowModjoin: boolean;\n\tautoconfirmedOnly: boolean;\n\tforceTimer: boolean;\n\tautostartcap: boolean;\n\tforcePublic: boolean;\n\tisTournamentStarted: boolean;\n\tisBracketInvalidated: boolean;\n\tlastBracketUpdate: number;\n\tbracketUpdateTimer: NodeJS.Timeout | null;\n\tbracketCache: AnyObject | null;\n\tisAvailableMatchesInvalidated: boolean;\n\tavailableMatchesCache: {\n\t\tchallenges: Map, challengeBys: Map,\n\t};\n\tautoDisqualifyTimeout: number;\n\tautoDisqualifyTimer: NodeJS.Timeout | null;\n\tautoStartTimeout: number;\n\tautoStartTimer: NodeJS.Timeout | null;\n\n\tconstructor(\n\t\troom: ChatRoom, format: Format, generator: Generator,\n\t\tplayerCap: string | undefined, isRated: boolean, name: string | undefined\n\t) {\n\t\tsuper(room);\n\t\tconst formatId = toID(format);\n\n\t\tthis.title = format.name + ' tournament';\n\t\tthis.isTournament = true;\n\t\tthis.completedMatches = new Set();\n\t\tthis.allowRenames = false;\n\t\tthis.playerCap = (playerCap ? parseInt(playerCap) : Config.tourdefaultplayercap) || 0;\n\n\t\tthis.baseFormat = formatId;\n\t\tthis.fullFormat = formatId;\n\t\t// This will sometimes be sent alone in updates as \"format\", if the tour doesn't have a custom name\n\t\tthis.name = name || formatId;\n\t\tthis.customRules = [];\n\t\tthis.generator = generator;\n\t\tthis.isRated = isRated;\n\t\tthis.allowScouting = true;\n\t\tthis.allowModjoin = false;\n\t\tthis.autoconfirmedOnly = false;\n\t\tthis.forceTimer = false;\n\t\tthis.autostartcap = false;\n\t\tthis.forcePublic = false;\n\t\tif (Config.tourdefaultplayercap && this.playerCap > Config.tourdefaultplayercap) {\n\t\t\tMonitor.log(`[TourMonitor] Room ${room.roomid} starting a tour over default cap (${this.playerCap})`);\n\t\t}\n\n\t\tthis.isTournamentStarted = false;\n\n\t\tthis.isBracketInvalidated = true;\n\t\tthis.lastBracketUpdate = 0;\n\t\tthis.bracketUpdateTimer = null;\n\t\tthis.bracketCache = null;\n\n\t\tthis.isAvailableMatchesInvalidated = true;\n\t\tthis.availableMatchesCache = { challenges: new Map(), challengeBys: new Map() };\n\n\t\tthis.autoDisqualifyTimeout = Infinity;\n\t\tthis.autoDisqualifyTimer = null;\n\t\tthis.autoStartTimeout = Infinity;\n\t\tthis.autoStartTimer = null;\n\n\t\troom.add(`|tournament|create|${this.baseFormat}|${generator.name}|${this.playerCap}${this.name === this.baseFormat ? `` : `|${this.name}`}`);\n\t\tconst update: {\n\t\t\tformat: string, teambuilderFormat?: string, generator: string,\n\t\t\tplayerCap: number, isStarted: boolean, isJoined: boolean,\n\t\t} = {\n\t\t\tformat: this.name,\n\t\t\tgenerator: generator.name,\n\t\t\tplayerCap: this.playerCap,\n\t\t\tisStarted: false,\n\t\t\tisJoined: false,\n\t\t};\n\t\tif (this.name !== this.baseFormat) update.teambuilderFormat = this.baseFormat;\n\t\troom.send(`|tournament|update|${JSON.stringify(update)}`);\n\t\tthis.update();\n\t}\n\tdestroy() {\n\t\tthis.forceEnd();\n\t}\n\tremove() {\n\t\tif (this.autoStartTimer) clearTimeout(this.autoStartTimer);\n\t\tif (this.autoDisqualifyTimer) clearTimeout(this.autoDisqualifyTimer);\n\t\tfor (const roomid of this.completedMatches) {\n\t\t\tconst room = Rooms.get(roomid) as GameRoom;\n\t\t\tif (room) room.tour = null;\n\t\t}\n\t\tthis.setEnded();\n\t\tthis.room.game = null;\n\t}\n\tgetRemainingPlayers() {\n\t\treturn this.players.filter(player => !player.isDisqualified && !player.isEliminated);\n\t}\n\n\tsetGenerator(generator: Generator, output: Chat.CommandContext) {\n\t\tif (this.isTournamentStarted) {\n\t\t\toutput.sendReply('|tournament|error|BracketFrozen');\n\t\t\treturn;\n\t\t}\n\n\t\tthis.generator = generator;\n\t\tthis.room.send(`|tournament|update|${JSON.stringify({ generator: generator.name })}`);\n\t\tthis.isBracketInvalidated = true;\n\t\tthis.update();\n\t\treturn true;\n\t}\n\n\tsetCustomRules(rules: string) {\n\t\tlet format;\n\t\ttry {\n\t\t\tconst tryFormat = Dex.formats.validate(`${this.baseFormat}@@@${rules}`);\n\t\t\tformat = Dex.formats.get(tryFormat, true);\n\n\t\t\t// In tours of formats with generated teams, custom rule errors should be checked for here,\n\t\t\t// since users can't edit their teams to avoid them at matching time\n\t\t\tif (format.team) {\n\t\t\t\tconst testTeamSeed = PRNG.generateSeed();\n\t\t\t\tconst testTeamGenerator = Teams.getGenerator(format, testTeamSeed);\n\t\t\t\ttestTeamGenerator.getTeam(); // Throws error if generation fails\n\t\t\t}\n\t\t\tthis.fullFormat = tryFormat;\n\t\t} catch (e: any) {\n\t\t\tthrow new Chat.ErrorMessage(`Custom rule error: ${e.message}`);\n\t\t}\n\n\t\tconst customRules = format.customRules;\n\t\tif (!customRules) {\n\t\t\tthrow new Chat.ErrorMessage(`Invalid rules.`);\n\t\t}\n\t\tthis.customRules = customRules;\n\t\tif (this.name === this.baseFormat) {\n\t\t\tthis.name = this.getDefaultCustomName();\n\t\t\tthis.room.send(`|tournament|update|${JSON.stringify({ format: this.name })}`);\n\t\t\tthis.update();\n\t\t}\n\t\treturn true;\n\t}\n\n\tgetCustomRules() {\n\t\tconst bans = [];\n\t\tconst unbans = [];\n\t\tconst restrictions = [];\n\t\tconst addedRules = [];\n\t\tconst removedRules = [];\n\t\tfor (const ban of this.customRules) {\n\t\t\tconst charAt0 = ban.charAt(0);\n\t\t\tif (charAt0 === '+') {\n\t\t\t\tunbans.push(ban.substr(1));\n\t\t\t} else if (charAt0 === '-') {\n\t\t\t\tbans.push(ban.substr(1));\n\t\t\t} else if (charAt0 === '*') {\n\t\t\t\trestrictions.push(ban.substr(1));\n\t\t\t} else if (charAt0 === '!') {\n\t\t\t\tremovedRules.push(ban.substr(1));\n\t\t\t} else {\n\t\t\t\taddedRules.push(ban);\n\t\t\t}\n\t\t}\n\t\tconst html = [];\n\t\tif (bans.length) html.push(Utils.html`Added bans - ${bans.join(', ')}`);\n\t\tif (unbans.length) html.push(Utils.html`Removed bans - ${unbans.join(', ')}`);\n\t\tif (restrictions.length) html.push(Utils.html`Added restrictions - ${restrictions.join(', ')}`);\n\t\tif (addedRules.length) html.push(Utils.html`Added rules - ${addedRules.join(', ')}`);\n\t\tif (removedRules.length) html.push(Utils.html`Removed rules - ${removedRules.join(', ')}`);\n\t\treturn html.join(`
`);\n\t}\n\n\tforceEnd() {\n\t\tif (this.isTournamentStarted) {\n\t\t\tif (this.autoDisqualifyTimer) clearTimeout(this.autoDisqualifyTimer);\n\t\t\tfor (const player of this.players) {\n\t\t\t\tconst match = player.inProgressMatch;\n\t\t\t\tif (match) {\n\t\t\t\t\tmatch.room.tour = null;\n\t\t\t\t\tmatch.room.setParent(null);\n\t\t\t\t\tmatch.room.addRaw(`
The tournament was forcefully ended.
You can finish playing, but this battle is no longer considered a tournament battle.
`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.room.add('|tournament|forceend');\n\t\tthis.remove();\n\t}\n\n\tupdateFor(targetUser: User, connection?: Connection | User) {\n\t\tif (!connection) connection = targetUser;\n\t\tif (this.ended) return;\n\n\t\tif ((!this.bracketUpdateTimer && this.isBracketInvalidated) ||\n\t\t\t(this.isTournamentStarted && this.isAvailableMatchesInvalidated)) {\n\t\t\tthis.room.add(\n\t\t\t\t\"Error: update() called with a target user when data invalidated: \" +\n\t\t\t\t`${!this.bracketUpdateTimer && this.isBracketInvalidated}, ` +\n\t\t\t\t`${this.isTournamentStarted && this.isAvailableMatchesInvalidated}` +\n\t\t\t\t\"; Please report this to an admin.\"\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tconst possiblePlayer = this.playerTable[targetUser.id];\n\t\tlet isJoined = false;\n\t\tif (possiblePlayer) {\n\t\t\tif (this.generator.name.includes(\"Elimination\")) {\n\t\t\t\tisJoined = !possiblePlayer.isEliminated && !possiblePlayer.isDisqualified;\n\t\t\t} else if (this.generator.name.includes(\"Round Robin\")) {\n\t\t\t\tif (possiblePlayer.isDisqualified) {\n\t\t\t\t\tisJoined = !possiblePlayer.isDisqualified;\n\t\t\t\t} else if ((this.generator as RoundRobin)?.matchesPerPlayer) {\n\t\t\t\t\tisJoined = possiblePlayer.games !== (this.generator as RoundRobin).matchesPerPlayer;\n\t\t\t\t} else if (!this.isTournamentStarted) {\n\t\t\t\t\tisJoined = true;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tisJoined = true;\n\t\t\t}\n\t\t}\n\t\tconst update: {\n\t\t\tformat: string, teambuilderFormat?: string, generator: string,\n\t\t\tisStarted: boolean, isJoined: boolean, bracketData: AnyObject,\n\t\t} = {\n\t\t\tformat: this.name,\n\t\t\tgenerator: this.generator.name,\n\t\t\tisStarted: this.isTournamentStarted,\n\t\t\tisJoined,\n\t\t\tbracketData: this.bracketCache!,\n\t\t};\n\t\tif (this.name !== this.baseFormat) update.teambuilderFormat = this.baseFormat;\n\t\tconnection.sendTo(this.room, `|tournament|update|${JSON.stringify(update)}`);\n\t\tif (this.isTournamentStarted && isJoined) {\n\t\t\tconst update2 = {\n\t\t\t\tchallenges: usersToNames(this.availableMatchesCache.challenges.get(this.playerTable[targetUser.id])!),\n\t\t\t\tchallengeBys: usersToNames(this.availableMatchesCache.challengeBys.get(this.playerTable[targetUser.id])!),\n\t\t\t};\n\t\t\tconnection.sendTo(this.room, `|tournament|update|${JSON.stringify(update2)}`);\n\n\t\t\tconst pendingChallenge = this.playerTable[targetUser.id].pendingChallenge;\n\t\t\tif (pendingChallenge) {\n\t\t\t\tif (pendingChallenge.to) {\n\t\t\t\t\tconnection.sendTo(this.room, `|tournament|update|${JSON.stringify({ challenging: pendingChallenge.to.name })}`);\n\t\t\t\t} else if (pendingChallenge.from) {\n\t\t\t\t\tconnection.sendTo(this.room, `|tournament|update|${JSON.stringify({ challenged: pendingChallenge.from.name })}`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tconnection.sendTo(this.room, '|tournament|updateEnd');\n\t}\n\n\tupdate() {\n\t\tif (this.ended) return;\n\t\tif (this.isBracketInvalidated) {\n\t\t\tif (Date.now() < this.lastBracketUpdate + BRACKET_MINIMUM_UPDATE_INTERVAL) {\n\t\t\t\tif (this.bracketUpdateTimer) clearTimeout(this.bracketUpdateTimer);\n\t\t\t\tthis.bracketUpdateTimer = setTimeout(() => {\n\t\t\t\t\tthis.bracketUpdateTimer = null;\n\t\t\t\t\tthis.update();\n\t\t\t\t}, BRACKET_MINIMUM_UPDATE_INTERVAL);\n\t\t\t} else {\n\t\t\t\tthis.lastBracketUpdate = Date.now();\n\n\t\t\t\tthis.bracketCache = this.getBracketData();\n\t\t\t\tthis.isBracketInvalidated = false;\n\t\t\t\tthis.room.send(`|tournament|update|${JSON.stringify({ bracketData: this.bracketCache })}`);\n\t\t\t}\n\t\t}\n\n\t\tif (this.isTournamentStarted && this.isAvailableMatchesInvalidated) {\n\t\t\tthis.availableMatchesCache = this.getAvailableMatches();\n\n\t\t\tthis.isAvailableMatchesInvalidated = false;\n\t\t\tfor (const [player, opponents] of this.availableMatchesCache.challenges) {\n\t\t\t\tplayer.sendRoom(`|tournament|update|${JSON.stringify({ challenges: usersToNames(opponents) })}`);\n\t\t\t}\n\t\t\tfor (const [player, opponents] of this.availableMatchesCache.challengeBys) {\n\t\t\t\tplayer.sendRoom(`|tournament|update|${JSON.stringify({ challengeBys: usersToNames(opponents) })}`);\n\t\t\t}\n\t\t}\n\t\tthis.room.send('|tournament|updateEnd');\n\t}\n\n\tstatic checkBanned(room: Room, user: User | string) {\n\t\treturn Punishments.hasRoomPunishType(room, toID(user), 'TOURBAN');\n\t}\n\n\tremoveBannedUser(userid: User | ID) {\n\t\tuserid = toID(userid);\n\t\tif (!(userid in this.playerTable)) return;\n\t\tif (this.isTournamentStarted) {\n\t\t\tconst player = this.playerTable[userid];\n\t\t\tif (!player.isDisqualified) {\n\t\t\t\tthis.disqualifyUser(userid);\n\t\t\t}\n\t\t} else {\n\t\t\tthis.removeUser(userid);\n\t\t}\n\t\tthis.room.update();\n\t}\n\n\taddUser(user: User, output: Chat.CommandContext) {\n\t\tif (!user.named) {\n\t\t\toutput.sendReply('|tournament|error|UserNotNamed');\n\t\t\treturn;\n\t\t}\n\n\t\tif (user.id in this.playerTable) {\n\t\t\toutput.sendReply('|tournament|error|UserAlreadyAdded');\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.playerCap && this.playerCount >= this.playerCap) {\n\t\t\toutput.sendReply('|tournament|error|Full');\n\t\t\treturn;\n\t\t}\n\n\t\tif (Tournament.checkBanned(this.room, user) || Punishments.isBattleBanned(user) || user.namelocked) {\n\t\t\toutput.sendReply('|tournament|error|Banned');\n\t\t\treturn;\n\t\t}\n\n\t\tif (\n\t\t\t(this.room.settings.tournaments?.autoconfirmedOnly || this.autoconfirmedOnly) &&\n\t\t\t!user.autoconfirmed && !user.trusted\n\t\t) {\n\t\t\tuser.popup(\"Signups for tournaments are only available for autoconfirmed users in this room.\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst gameCount = user.games.size;\n\t\tif (gameCount > 4) {\n\t\t\toutput.errorReply(\"Due to high load, you are limited to 4 games at the same time.\");\n\t\t\treturn;\n\t\t}\n\n\t\tif (!Config.noipchecks) {\n\t\t\tfor (const otherPlayer of this.players) {\n\t\t\t\tif (!otherPlayer) continue;\n\t\t\t\tconst otherUser = Users.get(otherPlayer.id);\n\t\t\t\tif (otherUser && otherUser.latestIp === user.latestIp) {\n\t\t\t\t\toutput.sendReply('|tournament|error|AltUserAlreadyAdded');\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (this.isTournamentStarted) {\n\t\t\toutput.sendReply(`|tournament|error|BracketFrozen`);\n\t\t\treturn;\n\t\t}\n\n\t\tconst player = this.addPlayer(user);\n\t\tif (!player) throw new Error(\"Failed to add player.\");\n\n\t\tthis.playerTable[user.id] = player;\n\t\tthis.room.add(`|tournament|join|${user.name}`);\n\t\tuser.sendTo(this.room, '|tournament|update|{\"isJoined\":true}');\n\t\tthis.isBracketInvalidated = true;\n\t\tthis.update();\n\t\tif (this.playerCount === this.playerCap) {\n\t\t\tif (this.autostartcap === true) {\n\t\t\t\tthis.startTournament(output);\n\t\t\t} else {\n\t\t\t\tthis.room.add(\"The tournament is now full.\");\n\t\t\t}\n\t\t}\n\t}\n\n\tmakePlayer(user: User | string | null) {\n\t\tconst num = this.players.length ? this.players[this.players.length - 1].num : 1;\n\t\treturn new TournamentPlayer(user, this, num);\n\t}\n\n\tremoveUser(userid: ID, output?: Chat.CommandContext) {\n\t\tconst player = this.playerTable[userid];\n\t\tif (!player) {\n\t\t\tif (output) output.sendReply('|tournament|error|UserNotAdded');\n\t\t\treturn;\n\t\t}\n\n\t\tthis.removePlayer(player);\n\t\tconst user = Users.get(userid);\n\t\tthis.room.add(`|tournament|leave|${user ? user.name : userid}`);\n\t\tif (user) user.sendTo(this.room, '|tournament|update|{\"isJoined\":false}');\n\t\tthis.isBracketInvalidated = true;\n\t\tthis.update();\n\t}\n\treplaceUser(user: User, replacementUser: User, output: Chat.CommandContext) {\n\t\tif (!this.isTournamentStarted) {\n\t\t\toutput.sendReply('|tournament|error|NotStarted');\n\t\t\treturn;\n\t\t}\n\t\tif (!(user.id in this.playerTable)) {\n\t\t\toutput.errorReply(`${user.name} isn't in the tournament.`);\n\t\t\treturn;\n\t\t}\n\t\tif (!replacementUser.named) {\n\t\t\toutput.errorReply(`${replacementUser.name} must be named to join the tournament.`);\n\t\t\treturn;\n\t\t}\n\t\tif (replacementUser.id in this.playerTable) {\n\t\t\toutput.errorReply(`${replacementUser.name} is already in the tournament.`);\n\t\t\treturn;\n\t\t}\n\t\tif (Tournament.checkBanned(this.room, replacementUser) || Punishments.isBattleBanned(replacementUser) ||\n\t\t\treplacementUser.namelocked) {\n\t\t\toutput.errorReply(`${replacementUser.name} is banned from joining tournaments.`);\n\t\t\treturn;\n\t\t}\n\t\tif ((this.room.settings.tournaments?.autoconfirmedOnly || this.autoconfirmedOnly) && !user.autoconfirmed) {\n\t\t\tuser.popup(\"Signups for tournaments are only available for autoconfirmed users in this room.\");\n\t\t\treturn;\n\t\t}\n\n\t\tif (!Config.noipchecks) {\n\t\t\tfor (const otherPlayer of this.players) {\n\t\t\t\tif (!otherPlayer) continue;\n\t\t\t\tconst otherUser = Users.get(otherPlayer.id);\n\t\t\t\tif (otherUser &&\n\t\t\t\t\totherUser.latestIp === replacementUser.latestIp &&\n\t\t\t\t\treplacementUser.latestIp !== user.latestIp) {\n\t\t\t\t\toutput.errorReply(`${replacementUser.name} already has an alt in the tournament.`);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (!(replacementUser.id in this.room.users)) {\n\t\t\toutput.errorReply(`${replacementUser.name} is not in this room (${this.room.title}).`);\n\t\t\treturn;\n\t\t}\n\t\tconst player = this.playerTable[user.id];\n\t\tif (player.pendingChallenge) {\n\t\t\tthis.cancelChallenge(user, output);\n\t\t}\n\n\t\t// Replace the player\n\t\tthis.setPlayerUser(player, replacementUser);\n\n\t\t// Reset and invalidate any in progress battles\n\t\tlet matchPlayer = null;\n\t\tif (player.inProgressMatch) {\n\t\t\tmatchPlayer = player;\n\t\t} else {\n\t\t\tfor (const p of this.players) {\n\t\t\t\tif (p.inProgressMatch && p.inProgressMatch.to === player) {\n\t\t\t\t\tmatchPlayer = p;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (matchPlayer?.inProgressMatch) {\n\t\t\tmatchPlayer.inProgressMatch.to.isBusy = false;\n\t\t\tmatchPlayer.isBusy = false;\n\n\t\t\tmatchPlayer.inProgressMatch.room.addRaw(\n\t\t\t\tUtils.html`
${user.name} is no longer in the tournament.
` +\n\t\t\t\t`You can finish playing, but this battle is no longer considered a tournament battle.
`\n\t\t\t).update();\n\t\t\tmatchPlayer.inProgressMatch.room.setParent(null);\n\t\t\tthis.completedMatches.add(matchPlayer.inProgressMatch.room.roomid);\n\t\t\tmatchPlayer.inProgressMatch = null;\n\t\t}\n\n\t\tthis.isAvailableMatchesInvalidated = true;\n\t\tthis.isBracketInvalidated = true;\n\t\t// Update the bracket\n\t\tthis.update();\n\t\tthis.updateFor(user);\n\t\tthis.updateFor(replacementUser);\n\t\tconst challengePlayer = player.pendingChallenge &&\n\t\t\t(player.pendingChallenge.from || player.pendingChallenge.to);\n\t\tif (challengePlayer) {\n\t\t\tconst challengeUser = Users.getExact(challengePlayer.id);\n\t\t\tif (challengeUser) this.updateFor(challengeUser);\n\t\t}\n\n\t\tthis.room.add(`|tournament|replace|${user.name}|${replacementUser.name}`);\n\t\treturn true;\n\t}\n\n\tgetBracketData() {\n\t\tlet data: any;\n\t\tif (!this.isTournamentStarted) {\n\t\t\tdata = this.generator.getPendingBracketData(this.players);\n\t\t} else {\n\t\t\tdata = this.generator.getBracketData();\n\t\t}\n\t\tif (data.type === 'tree') {\n\t\t\tif (!data.rootNode) {\n\t\t\t\tdata.users = usersToNames(this.players.sort());\n\t\t\t\treturn data;\n\t\t\t}\n\t\t\tconst queue = [data.rootNode];\n\t\t\twhile (queue.length > 0) {\n\t\t\t\tconst node = queue.shift();\n\n\t\t\t\tif (node.state === 'available') {\n\t\t\t\t\tconst pendingChallenge = node.children[0].team.pendingChallenge;\n\t\t\t\t\tif (pendingChallenge && node.children[1].team === pendingChallenge.to) {\n\t\t\t\t\t\tnode.state = 'challenging';\n\t\t\t\t\t}\n\n\t\t\t\t\tconst inProgressMatch = node.children[0].team.inProgressMatch;\n\t\t\t\t\tif (inProgressMatch && node.children[1].team === inProgressMatch.to) {\n\t\t\t\t\t\tnode.state = 'inprogress';\n\t\t\t\t\t\tnode.room = inProgressMatch.room.roomid;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (node.team && typeof node.team !== 'string') {\n\t\t\t\t\tnode.team = node.team.name;\n\t\t\t\t}\n\n\t\t\t\tif (node.children) {\n\t\t\t\t\tfor (const child of node.children) {\n\t\t\t\t\t\tqueue.push(child);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else if (data.type === 'table') {\n\t\t\tif (this.isTournamentStarted) {\n\t\t\t\tfor (const [r, row] of data.tableContents.entries()) {\n\t\t\t\t\tconst pendingChallenge = data.tableHeaders.rows[r].pendingChallenge;\n\t\t\t\t\tconst inProgressMatch = data.tableHeaders.rows[r].inProgressMatch;\n\t\t\t\t\tif (pendingChallenge || inProgressMatch) {\n\t\t\t\t\t\tfor (const [c, cell] of row.entries()) {\n\t\t\t\t\t\t\tif (!cell) continue;\n\n\t\t\t\t\t\t\tif (pendingChallenge && data.tableHeaders.cols[c] === pendingChallenge.to) {\n\t\t\t\t\t\t\t\tcell.state = 'challenging';\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (inProgressMatch && data.tableHeaders.cols[c] === inProgressMatch.to) {\n\t\t\t\t\t\t\t\tcell.state = 'inprogress';\n\t\t\t\t\t\t\t\tcell.room = inProgressMatch.room.roomid;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tdata.tableHeaders.cols = usersToNames(data.tableHeaders.cols);\n\t\t\tdata.tableHeaders.rows = usersToNames(data.tableHeaders.rows);\n\t\t}\n\t\treturn data;\n\t}\n\n\tstartTournament(output: Chat.CommandContext, isAutostart?: boolean) {\n\t\tif (this.isTournamentStarted) {\n\t\t\toutput.sendReply('|tournament|error|AlreadyStarted');\n\t\t\treturn false;\n\t\t}\n\n\t\tif (this.players.length < 2) {\n\t\t\tif (isAutostart) {\n\t\t\t\tthis.room.send('|tournament|error|NotEnoughUsers');\n\t\t\t\tthis.forceEnd();\n\t\t\t\tthis.room.update();\n\t\t\t\toutput.modlog('TOUR END');\n\t\t\t} else { // manual tour start without enough users\n\t\t\t\toutput.sendReply('|tournament|error|NotEnoughUsers');\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\tthis.generator.freezeBracket(this.players);\n\n\t\tconst now = Date.now();\n\t\tfor (const user of this.players) {\n\t\t\tuser.lastActionTime = now;\n\t\t}\n\n\t\tthis.isTournamentStarted = true;\n\t\tif (this.autoStartTimer) clearTimeout(this.autoStartTimer);\n\t\tif (this.autoDisqualifyTimeout !== Infinity) {\n\t\t\tthis.autoDisqualifyTimer = setTimeout(() => this.runAutoDisqualify(), this.autoDisqualifyTimeout);\n\t\t}\n\t\tthis.isBracketInvalidated = true;\n\t\tthis.room.add(`|tournament|start|${this.players.length}`);\n\t\toutput.modlog('TOUR START', null, `${this.players.length} players`);\n\t\tthis.room.send('|tournament|update|{\"isStarted\":true}');\n\t\tthis.update();\n\t\treturn true;\n\t}\n\tgetAvailableMatches() {\n\t\tconst matches = this.generator.getAvailableMatches() as [TournamentPlayer, TournamentPlayer][];\n\t\tif (typeof matches === 'string') throw new Error(`Error from getAvailableMatches(): ${matches}`);\n\n\t\tconst challenges = new Map();\n\t\tconst challengeBys = new Map();\n\t\tconst oldAvailableMatches = new Map();\n\n\t\tfor (const user of this.players) {\n\t\t\tchallenges.set(user, []);\n\t\t\tchallengeBys.set(user, []);\n\n\t\t\tlet oldAvailableMatch = false;\n\t\t\tconst availableMatches = user.availableMatches;\n\t\t\tif (availableMatches.size) {\n\t\t\t\toldAvailableMatch = true;\n\t\t\t\tavailableMatches.clear();\n\t\t\t}\n\t\t\toldAvailableMatches.set(user, oldAvailableMatch);\n\t\t}\n\n\t\tfor (const match of matches) {\n\t\t\tchallenges.get(match[0])!.push(match[1]);\n\t\t\tchallengeBys.get(match[1])!.push(match[0]);\n\n\t\t\tmatch[0].availableMatches.add(match[1]);\n\t\t}\n\n\t\tconst now = Date.now();\n\t\tfor (const player of this.players) {\n\t\t\tif (oldAvailableMatches.get(player)) continue;\n\n\t\t\tif (player.availableMatches.size) player.lastActionTime = now;\n\t\t}\n\n\t\treturn {\n\t\t\tchallenges,\n\t\t\tchallengeBys,\n\t\t};\n\t}\n\n\tdisqualifyUser(userid: ID, output: Chat.CommandContext | null = null, reason: string | null = null, isSelfDQ = false) {\n\t\tconst user = Users.get(userid);\n\t\tlet sendReply: (msg: string) => void;\n\t\tif (output) {\n\t\t\tsendReply = msg => output.sendReply(msg);\n\t\t} else if (user) {\n\t\t\tsendReply = msg => user.sendTo(this.roomid, msg);\n\t\t} else {\n\t\t\tsendReply = () => {};\n\t\t}\n\t\tif (!this.isTournamentStarted) {\n\t\t\tsendReply('|tournament|error|NotStarted');\n\t\t\treturn false;\n\t\t}\n\n\t\tif (!(userid in this.playerTable)) {\n\t\t\tsendReply(`|tournament|error|UserNotAdded|${userid}`);\n\t\t\treturn false;\n\t\t}\n\n\t\tconst player = this.playerTable[userid];\n\t\tif (player.isDisqualified) {\n\t\t\tsendReply(`|tournament|error|AlreadyDisqualified|${userid}`);\n\t\t\treturn false;\n\t\t}\n\n\t\tplayer.isDisqualified = true;\n\n\t\tconst error = this.generator.disqualifyUser(player);\n\t\tif (error) {\n\t\t\tsendReply(`|tournament|error|${error}`);\n\t\t\treturn false;\n\t\t}\n\n\t\tplayer.isBusy = false;\n\n\t\tconst challenge = player.pendingChallenge;\n\t\tif (challenge) {\n\t\t\tplayer.pendingChallenge = null;\n\t\t\tif (challenge.to) {\n\t\t\t\tchallenge.to.isBusy = false;\n\t\t\t\tchallenge.to.pendingChallenge = null;\n\t\t\t\tchallenge.to.sendRoom('|tournament|update|{\"challenged\":null}');\n\t\t\t} else if (challenge.from) {\n\t\t\t\tchallenge.from.isBusy = false;\n\t\t\t\tchallenge.from.pendingChallenge = null;\n\t\t\t\tchallenge.from.sendRoom('|tournament|update|{\"challenging\":null}');\n\t\t\t}\n\t\t}\n\n\t\tconst matchFrom = player.inProgressMatch;\n\t\tif (matchFrom) {\n\t\t\tmatchFrom.to.isBusy = false;\n\t\t\tplayer.inProgressMatch = null;\n\t\t\tmatchFrom.room.setParent(null);\n\t\t\tthis.completedMatches.add(matchFrom.room.roomid);\n\t\t\tmatchFrom.room.game?.forfeit?.(player.name);\n\t\t}\n\n\t\tlet matchTo = null;\n\t\tfor (const playerFrom of this.players) {\n\t\t\tconst match = playerFrom.inProgressMatch;\n\t\t\tif (match && match.to === player) matchTo = playerFrom;\n\t\t}\n\t\tif (matchTo) {\n\t\t\tmatchTo.isBusy = false;\n\t\t\tconst matchRoom = matchTo.inProgressMatch!.room;\n\t\t\tmatchRoom.setParent(null);\n\t\t\tthis.completedMatches.add(matchRoom.roomid);\n\t\t\tif (matchRoom.game) matchRoom.game.forfeit?.(player.id);\n\t\t\tmatchTo.inProgressMatch = null;\n\t\t}\n\n\t\tif (isSelfDQ) {\n\t\t\tthis.room.add(`|tournament|leave|${player.name}`);\n\t\t} else {\n\t\t\tthis.room.add(`|tournament|disqualify|${player.name}`);\n\t\t}\n\t\tif (user) {\n\t\t\tuser.sendTo(this.room, '|tournament|update|{\"isJoined\":false}');\n\t\t\tuser.popup(`|modal|You have been disqualified from the tournament in ${this.room.title}${reason ? `:\\n\\n${reason}` : `.`}`);\n\t\t}\n\t\tthis.isBracketInvalidated = true;\n\t\tthis.isAvailableMatchesInvalidated = true;\n\n\t\tif (this.generator.isTournamentEnded()) {\n\t\t\tthis.onTournamentEnd();\n\t\t} else {\n\t\t\tthis.update();\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tsetAutoStartTimeout(timeout: number, output: Chat.CommandContext) {\n\t\tif (this.isTournamentStarted) {\n\t\t\toutput.sendReply('|tournament|error|AlreadyStarted');\n\t\t\treturn false;\n\t\t}\n\t\tif (timeout < AUTO_START_MINIMUM_TIMEOUT || isNaN(timeout)) {\n\t\t\toutput.sendReply('|tournament|error|InvalidAutoStartTimeout');\n\t\t\treturn false;\n\t\t}\n\n\t\tif (this.autoStartTimer) clearTimeout(this.autoStartTimer);\n\t\tif (timeout === Infinity) {\n\t\t\tthis.room.add('|tournament|autostart|off');\n\t\t} else {\n\t\t\tthis.autoStartTimer = setTimeout(() => this.startTournament(output, true), timeout);\n\t\t\tthis.room.add(`|tournament|autostart|on|${timeout}`);\n\t\t}\n\t\tthis.autoStartTimeout = timeout;\n\n\t\treturn true;\n\t}\n\n\tsetAutoDisqualifyTimeout(timeout: number, output: Chat.CommandContext) {\n\t\tif (\n\t\t\tisNaN(timeout) || timeout < AUTO_DISQUALIFY_WARNING_TIMEOUT ||\n\t\t\t(timeout > MAX_AUTO_DISQUALIFY_TIMEOUT && timeout !== Infinity)\n\t\t) {\n\t\t\toutput.sendReply('|tournament|error|InvalidAutoDisqualifyTimeout');\n\t\t\treturn false;\n\t\t}\n\n\t\tthis.autoDisqualifyTimeout = timeout;\n\t\tif (this.autoDisqualifyTimeout === Infinity) {\n\t\t\tthis.room.add('|tournament|autodq|off');\n\t\t\tif (this.autoDisqualifyTimer) clearTimeout(this.autoDisqualifyTimer);\n\t\t\tfor (const player of this.players) player.autoDisqualifyWarned = false;\n\t\t} else {\n\t\t\tthis.room.add(`|tournament|autodq|on|${this.autoDisqualifyTimeout}`);\n\t\t\tif (this.isTournamentStarted) this.runAutoDisqualify();\n\t\t}\n\n\t\treturn true;\n\t}\n\trunAutoDisqualify(output?: Chat.CommandContext) {\n\t\tif (!this.isTournamentStarted) {\n\t\t\tif (output) output.sendReply('|tournament|error|NotStarted');\n\t\t\treturn false;\n\t\t}\n\t\tif (this.autoDisqualifyTimer) clearTimeout(this.autoDisqualifyTimer);\n\n\t\tconst now = Date.now();\n\t\tfor (const player of this.players) {\n\t\t\tconst time = player.lastActionTime;\n\t\t\tlet availableMatches = false;\n\t\t\tif (player.availableMatches.size) availableMatches = true;\n\t\t\tconst pendingChallenge = player.pendingChallenge;\n\n\t\t\tif (!availableMatches && !pendingChallenge) {\n\t\t\t\tplayer.autoDisqualifyWarned = false;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (pendingChallenge?.to) continue;\n\n\t\t\tif (now > time + this.autoDisqualifyTimeout && player.autoDisqualifyWarned) {\n\t\t\t\tlet reason;\n\t\t\t\tif (pendingChallenge?.from) {\n\t\t\t\t\treason = \"You failed to accept your opponent's challenge in time.\";\n\t\t\t\t} else {\n\t\t\t\t\treason = \"You failed to challenge your opponent in time.\";\n\t\t\t\t}\n\t\t\t\tthis.disqualifyUser(player.id, output, reason);\n\t\t\t\tthis.room.update();\n\t\t\t} else if (now > time + this.autoDisqualifyTimeout - AUTO_DISQUALIFY_WARNING_TIMEOUT) {\n\t\t\t\tif (player.autoDisqualifyWarned) continue;\n\t\t\t\tlet remainingTime = this.autoDisqualifyTimeout - now + time;\n\t\t\t\tif (remainingTime <= 0) {\n\t\t\t\t\tremainingTime = AUTO_DISQUALIFY_WARNING_TIMEOUT;\n\t\t\t\t\tplayer.lastActionTime = now - this.autoDisqualifyTimeout + AUTO_DISQUALIFY_WARNING_TIMEOUT;\n\t\t\t\t}\n\n\t\t\t\tplayer.autoDisqualifyWarned = true;\n\t\t\t\tplayer.sendRoom(`|tournament|autodq|target|${remainingTime}`);\n\t\t\t} else {\n\t\t\t\tplayer.autoDisqualifyWarned = false;\n\t\t\t}\n\t\t}\n\t\tif (!this.ended) this.autoDisqualifyTimer = setTimeout(() => this.runAutoDisqualify(), this.autoDisqualifyTimeout);\n\n\t\tif (output) output.sendReply(\"All available matches were checked for automatic disqualification.\");\n\t}\n\n\tsetScouting(allowed: boolean) {\n\t\tthis.allowScouting = allowed;\n\t\tthis.allowModjoin = !allowed;\n\t\tthis.room.add(`|tournament|scouting|${this.allowScouting ? 'allow' : 'disallow'}`);\n\t}\n\tsetModjoin(allowed: boolean) {\n\t\tthis.allowModjoin = allowed;\n\t\tthis.room.add(`Modjoining is now ${allowed ? 'allowed' : 'banned'} (Players can${allowed ? '' : 'not'} modjoin their tournament battles).`);\n\t}\n\tsetAutoconfirmedOnly(acOnly: boolean) {\n\t\tthis.autoconfirmedOnly = acOnly;\n\t\tthis.room.add(`This tournament is now ${acOnly ? 'dis' : ''}allowing non-autoconfirmed users' joining.`);\n\t}\n\tsetForceTimer(force: boolean) {\n\t\tthis.forceTimer = force;\n\t\tthis.room.add(`Forcetimer is now ${force ? 'on' : 'off'} for the tournament.`);\n\t}\n\tsetForcePublic(force: boolean) {\n\t\tthis.forcePublic = force;\n\t\tthis.room.add(`Tournament battles forced public: ${force ? 'ON' : 'OFF'}`);\n\t}\n\tsetAutostartAtCap(autostart: boolean) {\n\t\tthis.autostartcap = true;\n\t\tthis.room.add(`The tournament will start once ${this.playerCap} players have joined.`);\n\t}\n\n\tasync challenge(user: User, targetUserid: ID, output: Chat.CommandContext) {\n\t\tif (!this.isTournamentStarted) {\n\t\t\toutput.sendReply('|tournament|error|NotStarted');\n\t\t\treturn;\n\t\t}\n\n\t\tif (!(user.id in this.playerTable)) {\n\t\t\toutput.sendReply('|tournament|error|UserNotAdded');\n\t\t\treturn;\n\t\t}\n\n\t\tif (!(targetUserid in this.playerTable)) {\n\t\t\toutput.sendReply('|tournament|error|InvalidMatch');\n\t\t\treturn;\n\t\t}\n\n\t\tconst from = this.playerTable[user.id];\n\t\tconst to = this.playerTable[targetUserid];\n\t\tconst availableMatches = from.availableMatches;\n\t\tif (!availableMatches?.has(to)) {\n\t\t\toutput.sendReply('|tournament|error|InvalidMatch');\n\t\t\treturn;\n\t\t}\n\n\t\tif (from.isBusy || to.isBusy) {\n\t\t\tthis.room.add(\"Tournament backend breaks specifications. Please report this to an admin.\");\n\t\t\treturn;\n\t\t}\n\n\t\tfrom.isBusy = true;\n\t\tto.isBusy = true;\n\n\t\tthis.isAvailableMatchesInvalidated = true;\n\t\tthis.update();\n\n\t\tconst ready = await Ladders(this.fullFormat).prepBattle(output.connection, 'tour');\n\t\tif (!ready) {\n\t\t\tfrom.isBusy = false;\n\t\t\tto.isBusy = false;\n\n\t\t\tthis.isAvailableMatchesInvalidated = true;\n\t\t\tthis.update();\n\t\t\treturn;\n\t\t}\n\n\t\tto.lastActionTime = Date.now();\n\t\tfrom.pendingChallenge = {\n\t\t\tto, team: ready.settings.team, hidden: ready.settings.hidden, inviteOnly: ready.settings.inviteOnly,\n\t\t};\n\t\tto.pendingChallenge = {\n\t\t\tfrom, team: ready.settings.team, hidden: ready.settings.hidden, inviteOnly: ready.settings.inviteOnly,\n\t\t};\n\t\tfrom.sendRoom(`|tournament|update|${JSON.stringify({ challenging: to.name })}`);\n\t\tto.sendRoom(`|tournament|update|${JSON.stringify({ challenged: from.name })}`);\n\n\t\tthis.isBracketInvalidated = true;\n\t\tthis.update();\n\t}\n\tcancelChallenge(user: User, output: Chat.CommandContext) {\n\t\tif (!this.isTournamentStarted) {\n\t\t\tif (output) output.sendReply('|tournament|error|NotStarted');\n\t\t\treturn;\n\t\t}\n\n\t\tif (!(user.id in this.playerTable)) {\n\t\t\tif (output) output.sendReply('|tournament|error|UserNotAdded');\n\t\t\treturn;\n\t\t}\n\n\t\tconst player = this.playerTable[user.id];\n\t\tconst challenge = player.pendingChallenge;\n\t\tif (!challenge?.to) return;\n\n\t\tplayer.isBusy = false;\n\t\tchallenge.to.isBusy = false;\n\t\tplayer.pendingChallenge = null;\n\t\tchallenge.to.pendingChallenge = null;\n\t\tuser.sendTo(this.room, '|tournament|update|{\"challenging\":null}');\n\t\tchallenge.to.sendRoom('|tournament|update|{\"challenged\":null}');\n\n\t\tthis.isBracketInvalidated = true;\n\t\tthis.isAvailableMatchesInvalidated = true;\n\t\tthis.update();\n\t}\n\tasync acceptChallenge(user: User, output: Chat.CommandContext) {\n\t\tif (!this.isTournamentStarted) {\n\t\t\toutput.sendReply('|tournament|error|NotStarted');\n\t\t\treturn;\n\t\t}\n\n\t\tif (!(user.id in this.playerTable)) {\n\t\t\toutput.sendReply('|tournament|error|UserNotAdded');\n\t\t\treturn;\n\t\t}\n\n\t\tconst player = this.playerTable[user.id];\n\t\tconst challenge = player.pendingChallenge;\n\t\tif (!challenge?.from) return;\n\n\t\tconst ready = await Ladders(this.fullFormat).prepBattle(output.connection, 'tour');\n\t\tif (!ready) return;\n\n\t\t// Prevent battles between offline users from starting\n\t\tconst from = Users.get(challenge.from.id);\n\t\tif (!from?.connected || !user.connected) return;\n\n\t\t// Prevent double accepts and users that have been disqualified while between these two functions\n\t\tif (!challenge.from.pendingChallenge) return;\n\t\tif (!player.pendingChallenge) return;\n\n\t\tconst room = Rooms.createBattle({\n\t\t\tformat: this.fullFormat,\n\t\t\tisPrivate: this.room.settings.isPrivate,\n\t\t\tplayers: [{\n\t\t\t\tuser: from,\n\t\t\t\tteam: challenge.team,\n\t\t\t\thidden: challenge.hidden,\n\t\t\t\tinviteOnly: challenge.inviteOnly,\n\t\t\t}, {\n\t\t\t\tuser,\n\t\t\t\tteam: ready.settings.team,\n\t\t\t\thidden: ready.settings.hidden,\n\t\t\t\tinviteOnly: ready.settings.inviteOnly,\n\t\t\t}],\n\t\t\trated: !Ladders.disabled && this.isRated,\n\t\t\tchallengeType: ready.challengeType,\n\t\t\ttour: this,\n\t\t\tparentid: this.roomid,\n\t\t});\n\n\t\tchallenge.from.pendingChallenge = null;\n\t\tplayer.pendingChallenge = null;\n\t\tfrom.sendTo(this.room, '|tournament|update|{\"challenging\":null}');\n\t\tuser.sendTo(this.room, '|tournament|update|{\"challenged\":null}');\n\n\t\t// server lockdown\n\t\tif (!room) return;\n\n\t\tchallenge.from.inProgressMatch = { to: player, room };\n\t\tthis.room.add(`|tournament|battlestart|${from.name}|${user.name}|${room.roomid}`).update();\n\n\t\tthis.isBracketInvalidated = true;\n\t\tif (this.autoDisqualifyTimeout !== Infinity) this.runAutoDisqualify();\n\t\tif (this.forceTimer) room.game.startTimer();\n\t\tthis.update();\n\t}\n\n\tgetDefaultCustomName() {\n\t\treturn Dex.formats.get(this.fullFormat).name + \" (with custom rules)\";\n\t}\n\tforfeit(user: User) {\n\t\treturn this.disqualifyUser(user.id, null, \"You left the tournament\", true);\n\t}\n\tonConnect(user: User, connection: Connection) {\n\t\tthis.updateFor(user, connection);\n\t}\n\tonUpdateConnection(user: User, connection: Connection) {\n\t\tthis.updateFor(user, connection);\n\t}\n\tonRename(user: User, oldUserid: ID) {\n\t\tif (oldUserid in this.playerTable) {\n\t\t\tthis.renamePlayer(user, oldUserid);\n\t\t}\n\n\t\tthis.updateFor(user);\n\t}\n\tonBattleJoin(room: GameRoom, user: User) {\n\t\tif (!room.p1 || !room.p2) return;\n\t\tif (this.allowScouting || this.ended || user.latestIp === room.p1.latestIp || user.latestIp === room.p2.latestIp) {\n\t\t\treturn;\n\t\t}\n\t\tif (user.can('makeroom')) return;\n\t\tfor (const otherPlayer of this.getRemainingPlayers()) {\n\t\t\tconst otherUser = Users.get(otherPlayer.id);\n\t\t\tif (otherUser && otherUser.latestIp === user.latestIp) {\n\t\t\t\treturn \"Scouting is banned: tournament players can't watch other tournament battles.\";\n\t\t\t}\n\t\t}\n\t}\n\tonBattleWin(room: GameRoom, winnerid: ID) {\n\t\tif (this.completedMatches.has(room.roomid)) return;\n\t\tthis.completedMatches.add(room.roomid);\n\t\troom.setParent(null);\n\t\tif (!room.game) throw new Error(\"onBattleWin called without a battle\");\n\t\tif (!room.p1 || !room.p2) throw new Error(\"onBattleWin called with missing players\");\n\t\tconst p1 = this.playerTable[room.p1.id];\n\t\tconst p2 = this.playerTable[room.p2.id];\n\t\tconst winner = this.playerTable[winnerid];\n\t\tconst score = (room.game as RoomBattle | BestOfGame).score || [0, 0];\n\n\t\tlet result: 'win' | 'loss' | 'draw' = 'draw';\n\t\tif (p1 === winner) {\n\t\t\tp1.score += 1;\n\t\t\tp1.wins += 1;\n\t\t\tp2.losses += 1;\n\t\t\tresult = 'win';\n\t\t} else if (p2 === winner) {\n\t\t\tp2.score += 1;\n\t\t\tp2.wins += 1;\n\t\t\tp1.losses += 1;\n\t\t\tresult = 'loss';\n\t\t}\n\n\t\tp1.isBusy = false;\n\t\tp2.isBusy = false;\n\t\tp1.inProgressMatch = null;\n\n\t\tthis.isBracketInvalidated = true;\n\t\tthis.isAvailableMatchesInvalidated = true;\n\n\t\tif (result === 'draw' && !this.generator.isDrawingSupported) {\n\t\t\tthis.room.add(`|tournament|battleend|${p1.name}|${p2.name}|${result}|${score.join(',')}|fail|${room.roomid}`);\n\n\t\t\tif (this.autoDisqualifyTimeout !== Infinity) this.runAutoDisqualify();\n\t\t\tthis.update();\n\t\t\treturn this.room.update();\n\t\t}\n\t\tif (result === 'draw') {\n\t\t\tp1.score += 0.5;\n\t\t\tp2.score += 0.5;\n\t\t}\n\t\tp1.games += 1;\n\t\tp2.games += 1;\n\t\tif (!(p1.isDisqualified || p2.isDisqualified)) {\n\t\t\t// If a player was disqualified, handle the results there\n\t\t\tconst error = this.generator.setMatchResult([p1, p2], result as 'win' | 'loss', score);\n\t\t\tif (error) {\n\t\t\t\t// Should never happen\n\t\t\t\treturn this.room.add(`Unexpected ${error} from setMatchResult([${room.p1.id}, ${room.p2.id}], ${result}, ${score}) in onBattleWin(${room.roomid}, ${winnerid}). Please report this to an admin.`).update();\n\t\t\t}\n\t\t}\n\t\tthis.room.add(`|tournament|battleend|${p1.name}|${p2.name}|${result}|${score.join(',')}|success|${room.roomid}`);\n\n\t\tif (this.generator.isTournamentEnded()) {\n\t\t\tif (!this.room.settings.isPrivate && this.generator.name.includes('Elimination') && !Config.autosavereplays) {\n\t\t\t\tconst uploader = Users.get(winnerid);\n\t\t\t\tif (uploader?.connections[0]) {\n\t\t\t\t\tvoid Chat.parse('/savereplay', room, uploader, uploader.connections[0]);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.onTournamentEnd();\n\t\t} else {\n\t\t\tif (this.autoDisqualifyTimeout !== Infinity) this.runAutoDisqualify();\n\t\t\tthis.update();\n\t\t}\n\t\tthis.room.update();\n\t}\n\tonTournamentEnd() {\n\t\tconst update = {\n\t\t\tresults: (this.generator.getResults() as TournamentPlayer[][]).map(usersToNames),\n\t\t\tformat: this.name,\n\t\t\tgenerator: this.generator.name,\n\t\t\tbracketData: this.getBracketData(),\n\t\t};\n\t\tthis.room.add(`|tournament|end|${JSON.stringify(update)}`);\n\t\tconst settings = this.room.settings.tournaments;\n\t\tif (settings?.recentToursLength) {\n\t\t\tif (!settings.recentTours) settings.recentTours = [];\n\t\t\tconst name = Dex.formats.get(this.name).exists ? Dex.formats.get(this.name).name :\n\t\t\t\t`${this.name} (${Dex.formats.get(this.baseFormat).name})`;\n\t\t\tsettings.recentTours.unshift({ name, baseFormat: this.baseFormat, time: Date.now() });\n\t\t\t// Use a while loop here in case the threshold gets lowered with /tour settings recenttours\n\t\t\t// to trim down multiple at once\n\t\t\twhile (settings.recentTours.length > settings.recentToursLength) {\n\t\t\t\tsettings.recentTours.pop();\n\t\t\t}\n\t\t\tthis.room.saveSettings();\n\t\t}\n\t\tthis.remove();\n\t}\n}\n\nfunction getGenerator(generator: string | undefined) {\n\tgenerator = toID(generator);\n\tswitch (generator) {\n\tcase 'elim': generator = 'elimination'; break;\n\tcase 'rr': generator = 'roundrobin'; break;\n\t}\n\treturn TournamentGenerators[generator as 'elimination' | 'roundrobin'];\n}\n\nfunction createTournamentGenerator(\n\tgeneratorName: string | undefined, modifier: string | undefined, output: Chat.CommandContext\n) {\n\tconst TourGenerator = getGenerator(generatorName);\n\tif (!TourGenerator) {\n\t\toutput.errorReply(`${generatorName} is not a valid type.`);\n\t\tconst generatorNames = Object.keys(TournamentGenerators).join(', ');\n\t\toutput.errorReply(`Valid types: ${generatorNames}`);\n\t\treturn;\n\t}\n\treturn new TourGenerator(modifier || '');\n}\nfunction createTournament(\n\troom: Room, formatId: string | undefined, generator: string | undefined, playerCap: string | undefined,\n\tisRated: boolean, generatorMod: string | undefined, name: string | undefined, output: Chat.CommandContext\n) {\n\tif (room.type !== 'chat') {\n\t\toutput.errorReply(\"Tournaments can only be created in chat rooms.\");\n\t\treturn;\n\t}\n\tif (room.game) {\n\t\toutput.errorReply(`You cannot have a tournament until the current room activity is over: ${room.game.title}`);\n\t\treturn;\n\t}\n\tif (Rooms.global.lockdown) {\n\t\toutput.errorReply(\"The server is restarting soon, so a tournament cannot be created.\");\n\t\treturn;\n\t}\n\tconst format = Dex.formats.get(formatId);\n\tif (format.effectType !== 'Format' || !format.tournamentShow) {\n\t\toutput.errorReply(`${format.id} is not a valid tournament format.`);\n\t\tvoid output.parse(`/tour formats`);\n\t\treturn;\n\t}\n\tconst settings = room.settings.tournaments;\n\tif (settings?.blockRecents && settings.recentTours && settings.recentToursLength) {\n\t\tconst recentTours = settings.recentTours.map(x => x.baseFormat);\n\t\tif (recentTours.includes(format.id)) {\n\t\t\toutput.errorReply(`A ${format.name} tournament was made too recently.`);\n\t\t\treturn;\n\t\t}\n\t}\n\tif (!getGenerator(generator)) {\n\t\toutput.errorReply(`${generator} is not a valid type.`);\n\t\tconst generators = Object.keys(TournamentGenerators).join(', ');\n\t\toutput.errorReply(`Valid types: ${generators}`);\n\t\treturn;\n\t}\n\tif (playerCap && parseInt(playerCap) < 2) {\n\t\toutput.errorReply(\"You cannot have a player cap that is less than 2.\");\n\t\treturn;\n\t}\n\tif (name?.trim().length) {\n\t\tif (output.checkChat(name) !== name) {\n\t\t\tthrow new Chat.ErrorMessage(`You cannot use filtered words in tour names.`);\n\t\t}\n\n\t\tif (name.length > MAX_CUSTOM_NAME_LENGTH) {\n\t\t\tthrow new Chat.ErrorMessage(`The tournament's name cannot exceed ${MAX_CUSTOM_NAME_LENGTH} characters.`);\n\t\t}\n\t\tif (name.includes('|')) throw new Chat.ErrorMessage(\"The tournament's name cannot include the | symbol.\");\n\t}\n\tconst tour = room.game = new Tournament(\n\t\troom, format, createTournamentGenerator(generator, generatorMod, output)!, playerCap, isRated, name\n\t);\n\tif (settings) {\n\t\tif (typeof settings.autostart === 'number') tour.setAutoStartTimeout(settings.autostart, output);\n\t\tif (settings.playerCap) {\n\t\t\ttour.playerCap = settings.playerCap;\n\t\t\tif (settings.autostart === true) tour.setAutostartAtCap(true);\n\t\t}\n\t\tif (settings.autodq) tour.setAutoDisqualifyTimeout(settings.autodq, output);\n\t\tif (settings.forcePublic) tour.setForcePublic(true);\n\t\tif (settings.forceTimer) tour.setForceTimer(true);\n\t\tif (settings.allowModjoin === false) tour.setModjoin(false);\n\t\tif (settings.allowScouting === false) tour.setScouting(false);\n\t}\n\treturn tour;\n}\n\nconst commands: Chat.ChatCommands = {\n\tpasttours: 'recenttours',\n\trecenttours(target, room, user) {\n\t\tthis.runBroadcast();\n\t\troom = this.requireRoom();\n\t\tif (!room.settings.tournaments?.recentToursLength) {\n\t\t\tthrow new Chat.ErrorMessage(`Recent tournaments aren't documented in this room.`);\n\t\t}\n\t\tif (!room.settings.tournaments?.recentTours?.length) {\n\t\t\tthrow new Chat.ErrorMessage(`There haven't been any documented tournaments in this room recently.`);\n\t\t}\n\t\t// Shorten array if the recentToursLength gets adjusted\n\t\tconst array = room.settings.tournaments.recentTours;\n\t\tconst { name, time } = array[0];\n\t\tlet buf = `The last tournament ended ${Chat.toDurationString(Date.now() - time)} ago - ${name}`;\n\t\tif (array.length > 1) {\n\t\t\tbuf += `
Previous tournaments: `;\n\t\t\tbuf += array.filter((x, i) => i !== 0).map(x => x.name).join(', ');\n\t\t}\n\t\tthis.sendReplyBox(buf);\n\t},\n\trecenttourshelp: [`/recenttours - Displays the n most recent tour(s), where n represents the number defined by staff (i.e. the 6 most recent tours).`],\n\n\ttour: 'tournament',\n\ttours: 'tournament',\n\ttournaments: 'tournament',\n\ttournament: {\n\t\t''(target, room, user) {\n\t\t\troom = this.requireRoom();\n\t\t\tif (!this.runBroadcast()) return;\n\t\t\tconst update = [];\n\t\t\tfor (const tourRoom of Rooms.rooms.values()) {\n\t\t\t\tconst tournament = tourRoom.getGame(Tournament);\n\t\t\t\tif (!tournament) continue;\n\t\t\t\tif (tourRoom.settings.isPrivate || tourRoom.settings.isPersonal || tourRoom.settings.staffRoom) continue;\n\t\t\t\tupdate.push({\n\t\t\t\t\troom: tourRoom.roomid, title: room.title, format: tournament.name,\n\t\t\t\t\tgenerator: tournament.generator.name, isStarted: tournament.isTournamentStarted,\n\t\t\t\t});\n\t\t\t}\n\t\t\tthis.sendReply(`|tournaments|info|${JSON.stringify(update)}`);\n\t\t},\n\t\thelp() {\n\t\t\treturn this.parse('/help tournament');\n\t\t},\n\t\tenable: 'toggle',\n\t\tdisable: 'toggle',\n\t\ttoggle(target, room, user, connection, cmd) {\n\t\t\tthrow new Chat.ErrorMessage(`${this.cmdToken}${this.fullCmd} has been deprecated. Instead, use \"${this.cmdToken}permissions set tournaments, [rank symbol]\".`);\n\t\t},\n\t\tannouncements: 'announce',\n\t\tannounce(target, room, user, connection, cmd) {\n\t\t\troom = this.requireRoom();\n\t\t\tthis.checkCan('gamemanagement', null, room);\n\t\t\tif (!target) {\n\t\t\t\tif (room.settings.tournaments?.announcements) {\n\t\t\t\t\treturn this.sendReply(\"Tournament announcements are enabled.\");\n\t\t\t\t} else {\n\t\t\t\t\treturn this.sendReply(\"Tournament announcements are disabled.\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst option = target.toLowerCase();\n\t\t\tif (this.meansYes(option)) {\n\t\t\t\tif (room.settings.tournaments?.announcements) return this.errorReply(\"Tournament announcements are already enabled.\");\n\t\t\t\tif (!room.settings.tournaments) room.settings.tournaments = {};\n\t\t\t\troom.settings.tournaments.announcements = true;\n\t\t\t\troom.saveSettings();\n\t\t\t\tthis.privateModAction(`Tournament announcements were enabled by ${user.name}`);\n\t\t\t\tthis.modlog('TOUR ANNOUNCEMENTS', null, 'ON');\n\t\t\t} else if (this.meansNo(option)) {\n\t\t\t\tif (!room.settings.tournaments?.announcements) return this.errorReply(\"Tournament announcements are already disabled.\");\n\t\t\t\tif (!room.settings.tournaments) room.settings.tournaments = {};\n\t\t\t\troom.settings.tournaments.announcements = false;\n\t\t\t\troom.saveSettings();\n\t\t\t\tthis.privateModAction(`Tournament announcements were disabled by ${user.name}`);\n\t\t\t\tthis.modlog('TOUR ANNOUNCEMENTS', null, 'OFF');\n\t\t\t} else {\n\t\t\t\treturn this.sendReply(`Usage: /tour ${cmd} `);\n\t\t\t}\n\n\t\t\troom.saveSettings();\n\t\t},\n\t\tnew: 'create',\n\t\tcreate(target, room, user, connection, cmd) {\n\t\t\troom = this.requireRoom();\n\t\t\tthis.checkCan('tournaments', null, room);\n\t\t\tconst [format, generator, cap, mod, name] = target.split(',').map(item => item.trim());\n\t\t\tif (!target || !format || !generator) {\n\t\t\t\treturn this.sendReply(`Usage: /tour ${cmd} , [, ]`);\n\t\t\t}\n\n\t\t\tconst tour: Tournament | undefined = createTournament(room, format, generator, cap, Config.ratedtours, mod, name, this);\n\t\t\tif (tour) {\n\t\t\t\tthis.privateModAction(`${user.name} created a tournament in ${tour.baseFormat} format.`);\n\t\t\t\tthis.modlog('TOUR CREATE', null, tour.baseFormat);\n\t\t\t\tif (room.settings.tournaments?.announcements) {\n\t\t\t\t\tconst tourRoom = Rooms.search(Config.tourroom || 'tournaments');\n\t\t\t\t\tif (tourRoom && tourRoom !== room) {\n\t\t\t\t\t\ttourRoom.addRaw(\n\t\t\t\t\t\t\tUtils.html``\n\t\t\t\t\t\t).update();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tformats(target, room, user) {\n\t\t\tif (!this.runBroadcast()) return;\n\t\t\tlet buf = ``;\n\t\t\tlet section = undefined;\n\t\t\tfor (const format of Dex.formats.all()) {\n\t\t\t\tif (!format.tournamentShow) continue;\n\t\t\t\tconst name = format.name.startsWith(`[Gen ${Dex.gen}] `) ? format.name.slice(8) : format.name;\n\t\t\t\tif (format.section !== section) {\n\t\t\t\t\tsection = format.section;\n\t\t\t\t\tbuf += Utils.html`
${section}:
• ${name}`;\n\t\t\t\t} else {\n\t\t\t\t\tbuf += Utils.html`
• ${name}`;\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.sendReplyBox(`
Valid Formats: ${buf}
`);\n\t\t},\n\t\tbanuser(target, room, user) {\n\t\t\troom = this.requireRoom();\n\t\t\tconst [userid, ...reasonsArray] = target.split(',').map(item => item.trim());\n\t\t\tif (!target) {\n\t\t\t\treturn this.sendReply(`Usage: /tour banuser , `);\n\t\t\t}\n\t\t\tconst reason = reasonsArray.join(',');\n\t\t\tconst targetUser = Users.get(userid);\n\t\t\tthis.checkCan('gamemoderation', targetUser, room);\n\n\t\t\tconst targetUserid = targetUser ? targetUser.id : toID(userid);\n\t\t\tif (!targetUser) return false;\n\t\t\tif (reason?.length > MAX_REASON_LENGTH) {\n\t\t\t\treturn this.errorReply(`The reason is too long. It cannot exceed ${MAX_REASON_LENGTH} characters.`);\n\t\t\t}\n\n\t\t\tif (Tournament.checkBanned(room, targetUser)) return this.errorReply(\"This user is already banned from tournaments.\");\n\n\t\t\tconst punishment = {\n\t\t\t\ttype: 'TOURBAN',\n\t\t\t\tid: targetUserid,\n\t\t\t\texpireTime: Date.now() + TOURBAN_DURATION,\n\t\t\t\treason,\n\t\t\t};\n\t\t\tif (targetUser) {\n\t\t\t\tPunishments.roomPunish(room, targetUser, punishment);\n\t\t\t} else {\n\t\t\t\tPunishments.roomPunishName(room, targetUserid, punishment);\n\t\t\t}\n\t\t\troom.getGame(Tournament)?.removeBannedUser(targetUserid);\n\n\t\t\tthis.modlog('TOURBAN', targetUser, reason);\n\t\t\tthis.privateModAction(\n\t\t\t\t`${targetUser ? targetUser.name : targetUserid} was banned from joining tournaments by ${user.name}. (${reason})`\n\t\t\t);\n\t\t},\n\t\tunbanuser(target, room, user) {\n\t\t\troom = this.requireRoom();\n\t\t\ttarget = target.trim();\n\t\t\tif (!target) {\n\t\t\t\treturn this.sendReply(`Usage: /tour unbanuser `);\n\t\t\t}\n\t\t\tconst targetUser = Users.get(toID(target));\n\t\t\tthis.checkCan('gamemoderation', targetUser, room);\n\n\t\t\tconst targetUserid = toID(targetUser || toID(target));\n\n\t\t\tif (!Tournament.checkBanned(room, targetUserid)) return this.errorReply(\"This user isn't banned from tournaments.\");\n\n\t\t\tif (targetUser) {\n\t\t\t\tPunishments.roomUnpunish(room, targetUserid, 'TOURBAN', false);\n\t\t\t}\n\t\t\tthis.privateModAction(`${targetUser ? targetUser.name : targetUserid} was unbanned from joining tournaments by ${user.name}.`);\n\t\t\tthis.modlog('TOUR UNBAN', targetUser, null, { noip: 1, noalts: 1 });\n\t\t},\n\t\tj: 'join',\n\t\tin: 'join',\n\t\tjoin(target, room, user) {\n\t\t\troom = this.requireRoom();\n\t\t\tconst tournament = this.requireGame(Tournament);\n\t\t\ttournament.addUser(user, this);\n\t\t},\n\t\tl: 'leave',\n\t\tout: 'leave',\n\t\tleave(target, room, user) {\n\t\t\troom = this.requireRoom();\n\t\t\tconst tournament = this.requireGame(Tournament);\n\t\t\tif (tournament.isTournamentStarted) {\n\t\t\t\tif (tournament.getRemainingPlayers().some(player => player.id === user.id)) {\n\t\t\t\t\ttournament.disqualifyUser(user.id, this, null, true);\n\t\t\t\t} else {\n\t\t\t\t\tthis.errorReply(\"You have already been eliminated from this tournament.\");\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\ttournament.removeUser(user.id, this);\n\t\t\t}\n\t\t},\n\t\tgetusers(target, room) {\n\t\t\tif (!this.runBroadcast()) return;\n\t\t\troom = this.requireRoom();\n\t\t\tconst tournament = this.requireGame(Tournament);\n\t\t\tconst users = usersToNames(tournament.getRemainingPlayers().sort());\n\t\t\tthis.sendReplyBox(\n\t\t\t\t`${users.length}/${tournament.players.length}` +\n\t\t\t\tUtils.html` users remain in this tournament:
${users.join(', ')}`\n\t\t\t);\n\t\t},\n\t\tgetupdate(target, room, user) {\n\t\t\troom = this.requireRoom();\n\t\t\tconst tournament = this.requireGame(Tournament);\n\t\t\ttournament.updateFor(user);\n\t\t\tthis.sendReply(\"Your tournament bracket has been updated.\");\n\t\t},\n\t\tchallenge(target, room, user, connection, cmd) {\n\t\t\troom = this.requireRoom();\n\t\t\tconst tournament = this.requireGame(Tournament);\n\t\t\tif (!target) {\n\t\t\t\treturn this.sendReply(`Usage: /tour ${cmd} `);\n\t\t\t}\n\t\t\tvoid tournament.challenge(user, toID(target), this);\n\t\t},\n\t\tcancelchallenge(target, room, user) {\n\t\t\troom = this.requireRoom();\n\t\t\tconst tournament = this.requireGame(Tournament);\n\t\t\ttournament.cancelChallenge(user, this);\n\t\t},\n\t\tacceptchallenge(target, room, user) {\n\t\t\troom = this.requireRoom();\n\t\t\tconst tournament = this.requireGame(Tournament);\n\t\t\tvoid tournament.acceptChallenge(user, this);\n\t\t},\n\t\tasync vtm(target, room, user, connection) {\n\t\t\troom = this.requireRoom();\n\t\t\tconst tournament = this.requireGame(Tournament);\n\t\t\tif (Monitor.countPrepBattle(connection.ip, connection)) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst result = await TeamValidatorAsync.get(tournament.fullFormat).validateTeam(user.battleSettings.team);\n\t\t\tif (result.startsWith('1')) {\n\t\t\t\tconnection.popup(\"Your team is valid for this tournament.\");\n\t\t\t} else {\n\t\t\t\tconst formatName = Dex.formats.get(tournament.baseFormat).name;\n\t\t\t\t// split/join is the easiest way to do a find/replace with an untrusted string, sadly\n\t\t\t\tconst reasons = result.slice(1).split(formatName).join('this tournament');\n\t\t\t\tconnection.popup(`Your team was rejected for the following reasons:\\n\\n- ${reasons.replace(/\\n/g, '\\n- ')}`);\n\t\t\t}\n\t\t},\n\t\tviewruleset: 'viewcustomrules',\n\t\tviewbanlist: 'viewcustomrules',\n\t\tviewrules: 'viewcustomrules',\n\t\tviewcustomrules(target, room) {\n\t\t\troom = this.requireRoom();\n\t\t\tconst tournament = this.requireGame(Tournament);\n\t\t\tif (!this.runBroadcast()) return;\n\t\t\tif (tournament.customRules.length < 1) {\n\t\t\t\treturn this.errorReply(\"The tournament does not have any custom rules.\");\n\t\t\t}\n\t\t\tthis.sendReply(`|html|
This tournament includes:
${tournament.getCustomRules()}
`);\n\t\t},\n\t\tsettype(target, room, user, connection, cmd) {\n\t\t\troom = this.requireRoom();\n\t\t\tthis.checkCan('tournaments', null, room);\n\t\t\tconst tournament = this.requireGame(Tournament);\n\t\t\tif (!target) {\n\t\t\t\treturn this.sendReply(`Usage: /tour ${cmd} [, ]`);\n\t\t\t}\n\t\t\tconst [generatorType, cap, modifier] = target.split(',').map(item => item.trim());\n\t\t\tconst playerCap = parseInt(cap);\n\t\t\tconst generator = createTournamentGenerator(generatorType, modifier, this);\n\t\t\tif (generator && tournament.setGenerator(generator, this)) {\n\t\t\t\tif (playerCap && playerCap >= 2) {\n\t\t\t\t\ttournament.playerCap = playerCap;\n\t\t\t\t\tif (Config.tourdefaultplayercap && tournament.playerCap > Config.tourdefaultplayercap) {\n\t\t\t\t\t\tMonitor.log(`[TourMonitor] Room ${tournament.room.roomid} starting a tour over default cap (${tournament.playerCap})`);\n\t\t\t\t\t}\n\t\t\t\t\troom.send(`|tournament|update|{\"playerCap\": \"${playerCap}\"}`);\n\t\t\t\t} else if (tournament.playerCap && !playerCap) {\n\t\t\t\t\ttournament.playerCap = 0;\n\t\t\t\t\troom.send(`|tournament|update|{\"playerCap\": \"${playerCap}\"}`);\n\t\t\t\t}\n\t\t\t\tconst capNote = (tournament.playerCap ? ` with a player cap of ${tournament.playerCap}` : '');\n\t\t\t\tthis.privateModAction(`${user.name} set tournament type to ${generator.name}${capNote}.`);\n\t\t\t\tthis.modlog('TOUR SETTYPE', null, `${generator.name}${capNote}`);\n\t\t\t\tthis.sendReply(`Tournament set to ${generator.name}${capNote}.`);\n\t\t\t}\n\t\t},\n\t\tcap: 'setplayercap',\n\t\tplayercap: 'setplayercap',\n\t\tsetcap: 'setplayercap',\n\t\tsetplayercap(target, room, user, connection, cmd) {\n\t\t\troom = this.requireRoom();\n\t\t\tthis.checkCan('tournaments', null, room);\n\t\t\tconst tournament = this.requireGame(Tournament);\n\t\t\ttarget = target.trim();\n\t\t\tif (!target) {\n\t\t\t\tif (tournament.playerCap) {\n\t\t\t\t\treturn this.sendReply(`Usage: /tour ${cmd} ; The current player cap is ${tournament.playerCap}`);\n\t\t\t\t} else {\n\t\t\t\t\treturn this.sendReply(`Usage: /tour ${cmd} `);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (tournament.isTournamentStarted) {\n\t\t\t\treturn this.errorReply(\"The player cap cannot be changed once the tournament has started.\");\n\t\t\t}\n\t\t\tconst option = target.toLowerCase();\n\t\t\tif (['0', 'infinity', 'off', 'false', 'stop', 'remove'].includes(option)) {\n\t\t\t\tif (!tournament.playerCap) return this.errorReply(\"The tournament does not have a player cap.\");\n\t\t\t\ttarget = '0';\n\t\t\t}\n\t\t\tconst playerCap = parseInt(target);\n\t\t\tif (playerCap === 0) {\n\t\t\t\ttournament.playerCap = 0;\n\t\t\t\tthis.privateModAction(`${user.name} removed the tournament's player cap.`);\n\t\t\t\tthis.modlog('TOUR PLAYERCAP', null, 'removed');\n\t\t\t\tthis.sendReply(\"Tournament cap removed.\");\n\t\t\t} else {\n\t\t\t\tif (isNaN(playerCap) || playerCap < 2) {\n\t\t\t\t\treturn this.errorReply(\"The tournament cannot have a player cap less than 2.\");\n\t\t\t\t}\n\t\t\t\tif (playerCap === tournament.playerCap) {\n\t\t\t\t\treturn this.errorReply(`The tournament's player cap is already ${playerCap}.`);\n\t\t\t\t}\n\t\t\t\ttournament.playerCap = playerCap;\n\t\t\t\tif (Config.tourdefaultplayercap && tournament.playerCap > Config.tourdefaultplayercap) {\n\t\t\t\t\tMonitor.log(`[TourMonitor] Room ${tournament.room.roomid} starting a tour over default cap (${tournament.playerCap})`);\n\t\t\t\t}\n\t\t\t\tthis.privateModAction(`${user.name} set the tournament's player cap to ${tournament.playerCap}.`);\n\t\t\t\tthis.modlog('TOUR PLAYERCAP', null, tournament.playerCap.toString());\n\t\t\t\tthis.sendReply(`Tournament cap set to ${tournament.playerCap}.`);\n\t\t\t}\n\t\t\troom.send(`|tournament|update|{\"playerCap\": \"${tournament.playerCap}\"}`);\n\t\t},\n\t\tend: 'delete',\n\t\tstop: 'delete',\n\t\tdelete(target, room, user) {\n\t\t\troom = this.requireRoom();\n\t\t\tthis.checkCan('tournaments', null, room);\n\t\t\tconst tournament = this.requireGame(Tournament);\n\t\t\ttournament.forceEnd();\n\t\t\tthis.privateModAction(`${user.name} forcibly ended a tournament.`);\n\t\t\tthis.modlog('TOUR END');\n\t\t},\n\t\truleset: 'customrules',\n\t\tbanlist: 'customrules',\n\t\trules: 'customrules',\n\t\tcustomrules(target, room, user, connection, cmd) {\n\t\t\troom = this.requireRoom();\n\t\t\tconst tournament = this.requireGame(Tournament);\n\t\t\tif (cmd === 'banlist') {\n\t\t\t\treturn this.errorReply('The new syntax is: /tour rules -bannedthing, +un[banned|restricted]thing, *restrictedthing, !removedrule, addedrule');\n\t\t\t}\n\t\t\tif (!target) {\n\t\t\t\tthis.sendReply(\"Usage: /tour rules \");\n\t\t\t\tthis.sendReply(\"Rules can be: -bannedthing, +un[banned|restricted]thing, *restrictedthing, !removedrule, addedrule\");\n\t\t\t\tthis.parse('/tour viewrules');\n\t\t\t\tif (tournament.customRules.length) {\n\t\t\t\t\treturn this.sendReplyBox(`
Source/tour rules ${tournament.customRules}
`);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.checkCan('tournaments', null, room);\n\t\t\tif (tournament.isTournamentStarted) {\n\t\t\t\treturn this.errorReply(\"The custom rules cannot be changed once the tournament has started.\");\n\t\t\t}\n\t\t\tif (tournament.setCustomRules(target)) {\n\t\t\t\troom.addRaw(\n\t\t\t\t\t`
This tournament includes:
${tournament.getCustomRules()}
`\n\t\t\t\t);\n\t\t\t\tthis.privateModAction(`${user.name} updated the tournament's custom rules.`);\n\t\t\t\tthis.modlog('TOUR RULES', null, tournament.customRules.join(', '));\n\t\t\t\tthis.sendReplyBox(`
Source/tour rules ${tournament.customRules}
`);\n\t\t\t}\n\t\t},\n\t\tclearruleset: 'clearcustomrules',\n\t\tclearbanlist: 'clearcustomrules',\n\t\tclearrules: 'clearcustomrules',\n\t\tclearcustomrules(target, room, user) {\n\t\t\troom = this.requireRoom();\n\t\t\tthis.checkCan('tournaments', null, room);\n\t\t\tconst tournament = this.requireGame(Tournament);\n\t\t\tif (tournament.isTournamentStarted) {\n\t\t\t\treturn this.errorReply(\"The custom rules cannot be changed once the tournament has started.\");\n\t\t\t}\n\t\t\tif (tournament.customRules.length < 1) {\n\t\t\t\treturn this.errorReply(\"The tournament does not have any custom rules.\");\n\t\t\t}\n\t\t\ttournament.customRules = [];\n\t\t\ttournament.fullFormat = tournament.baseFormat;\n\t\t\tif (tournament.name === tournament.getDefaultCustomName()) {\n\t\t\t\ttournament.name = tournament.baseFormat;\n\t\t\t\troom.send(`|tournament|update|${JSON.stringify({ format: tournament.name })}`);\n\t\t\t\ttournament.update();\n\t\t\t}\n\t\t\troom.addRaw(`The tournament's custom rules were cleared.`);\n\t\t\tthis.privateModAction(`${user.name} cleared the tournament's custom rules.`);\n\t\t\tthis.modlog('TOUR CLEARRULES');\n\t\t},\n\t\tname: 'setname',\n\t\tcustomname: 'setname',\n\t\tsetname(target, room, user, connection, cmd) {\n\t\t\troom = this.requireRoom();\n\t\t\tthis.checkCan('tournaments', null, room);\n\t\t\tconst tournament = this.requireGame(Tournament);\n\t\t\tconst name = target.trim();\n\t\t\tif (!name) {\n\t\t\t\treturn this.sendReply(`Usage: /tour ${cmd} `);\n\t\t\t}\n\t\t\tthis.checkChat(name);\n\t\t\tif (!name || typeof name !== 'string') return;\n\n\t\t\tif (name.length > MAX_CUSTOM_NAME_LENGTH) {\n\t\t\t\treturn this.errorReply(`The tournament's name cannot exceed ${MAX_CUSTOM_NAME_LENGTH} characters.`);\n\t\t\t}\n\t\t\tif (name.includes('|')) return this.errorReply(\"The tournament's name cannot include the | symbol.\");\n\t\t\ttournament.name = name;\n\t\t\troom.send(`|tournament|update|${JSON.stringify({ format: tournament.name })}`);\n\t\t\tthis.privateModAction(`${user.name} set the tournament's name to ${tournament.name}.`);\n\t\t\tthis.modlog('TOUR NAME', null, tournament.name);\n\t\t\ttournament.update();\n\t\t},\n\t\tresetname: 'clearname',\n\t\tclearname(target, room, user) {\n\t\t\troom = this.requireRoom();\n\t\t\tthis.checkCan('tournaments', null, room);\n\t\t\tconst tournament = this.requireGame(Tournament);\n\t\t\tif (tournament.name === tournament.baseFormat) return this.errorReply(\"The tournament does not have a name.\");\n\t\t\ttournament.name = tournament.baseFormat;\n\t\t\troom.send(`|tournament|update|${JSON.stringify({ format: tournament.name })}`);\n\t\t\tthis.privateModAction(`${user.name} cleared the tournament's name.`);\n\t\t\tthis.modlog('TOUR CLEARNAME');\n\t\t\ttournament.update();\n\t\t},\n\t\tbegin: 'start',\n\t\tstart(target, room, user) {\n\t\t\troom = this.requireRoom();\n\t\t\tthis.checkCan('tournaments', null, room);\n\t\t\tconst tournament = this.requireGame(Tournament);\n\t\t\tif (tournament.startTournament(this)) {\n\t\t\t\troom.sendMods(`(${user.name} started the tournament.)`);\n\t\t\t}\n\t\t},\n\t\tdq: 'disqualify',\n\t\tdisqualify(target, room, user, connection, cmd) {\n\t\t\troom = this.requireRoom();\n\t\t\tthis.checkCan('tournaments', null, room);\n\t\t\tconst tournament = this.requireGame(Tournament);\n\t\t\tif (!target) {\n\t\t\t\treturn this.sendReply(`Usage: /tour ${cmd} `);\n\t\t\t}\n\t\t\tconst [userid, reason] = target.split(',').map(item => item.trim());\n\t\t\tconst targetUser = Users.get(userid);\n\t\t\tconst targetUserid = toID(targetUser || userid);\n\t\t\tif (reason?.length > MAX_REASON_LENGTH) {\n\t\t\t\treturn this.errorReply(`The reason is too long. It cannot exceed ${MAX_REASON_LENGTH} characters.`);\n\t\t\t}\n\t\t\tif (tournament.disqualifyUser(targetUserid, this, reason)) {\n\t\t\t\tthis.privateModAction(`${(targetUser ? targetUser.name : targetUserid)} was disqualified from the tournament by ${user.name}${(reason ? ' (' + reason + ')' : '')}`);\n\t\t\t\tthis.modlog('TOUR DQ', targetUserid, reason);\n\t\t\t}\n\t\t},\n\t\tsub: 'replace',\n\t\treplace(target, room, user) {\n\t\t\troom = this.requireRoom();\n\t\t\tthis.checkCan('tournaments', null, room);\n\t\t\tconst tournament = this.requireGame(Tournament);\n\t\t\tconst [oldUser, newUser] = target.split(',').map(item => Users.get(item.trim()));\n\t\t\tif (!oldUser) return this.errorReply(`User ${oldUser} not found.`);\n\t\t\tif (!newUser) return this.errorReply(`User ${newUser} not found.`);\n\n\t\t\ttournament.replaceUser(oldUser, newUser, this);\n\t\t},\n\t\tautostart: 'setautostart',\n\t\tsetautostart(target, room, user, connection, cmd) {\n\t\t\troom = this.requireRoom();\n\t\t\tthis.checkCan('tournaments', null, room);\n\t\t\tconst tournament = this.requireGame(Tournament);\n\t\t\ttarget = target.trim();\n\t\t\tif (!target) {\n\t\t\t\treturn this.sendReply(`Usage: /tour ${cmd} `);\n\t\t\t}\n\t\t\tconst option = target.toLowerCase();\n\t\t\tif ((this.meansYes(option) && option !== '1') || option === 'start') {\n\t\t\t\tif (tournament.isTournamentStarted) {\n\t\t\t\t\treturn this.errorReply(\"The tournament has already started.\");\n\t\t\t\t} else if (!tournament.playerCap) {\n\t\t\t\t\treturn this.errorReply(\"The tournament does not have a player cap set.\");\n\t\t\t\t} else {\n\t\t\t\t\tif (tournament.autostartcap) {\n\t\t\t\t\t\treturn this.errorReply(\"The tournament is already set to autostart when the player cap is reached.\");\n\t\t\t\t\t}\n\t\t\t\t\ttournament.setAutostartAtCap(true);\n\t\t\t\t\tthis.privateModAction(`The tournament was set to autostart when the player cap is reached by ${user.name}`);\n\t\t\t\t\tthis.modlog('TOUR AUTOSTART', null, 'when playercap is reached');\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (option === '0' || option === 'infinity' || this.meansNo(option) || option === 'stop' || option === 'remove') {\n\t\t\t\t\tif (!tournament.autostartcap && tournament.autoStartTimeout === Infinity) {\n\t\t\t\t\t\treturn this.errorReply(\"The automatic tournament start timer is already off.\");\n\t\t\t\t\t}\n\t\t\t\t\ttarget = 'off';\n\t\t\t\t\ttournament.autostartcap = false;\n\t\t\t\t}\n\t\t\t\tconst timeout = target.toLowerCase() === 'off' ? Infinity : Number(target) * 60 * 1000;\n\t\t\t\tif (timeout <= 0 || (timeout !== Infinity && timeout > Chat.MAX_TIMEOUT_DURATION)) {\n\t\t\t\t\treturn this.errorReply(`The automatic tournament start timer must be set to a positive number.`);\n\t\t\t\t}\n\t\t\t\tif (tournament.setAutoStartTimeout(timeout, this)) {\n\t\t\t\t\tthis.privateModAction(`The tournament auto start timer was set to ${target} by ${user.name}`);\n\t\t\t\t\tthis.modlog('TOUR AUTOSTART', null, timeout === Infinity ? 'off' : target);\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tautodq: 'setautodq',\n\t\tsetautodq(target, room, user, connection, cmd) {\n\t\t\troom = this.requireRoom();\n\t\t\tthis.checkCan('tournaments', null, room);\n\t\t\tconst tournament = this.requireGame(Tournament);\n\t\t\ttarget = target.trim();\n\t\t\tif (!target) {\n\t\t\t\tif (tournament.autoDisqualifyTimeout !== Infinity) {\n\t\t\t\t\treturn this.sendReply(`Usage: /tour ${cmd} ; The current automatic disqualify timer is set to ${(tournament.autoDisqualifyTimeout / 1000 / 60)} minute(s)`);\n\t\t\t\t} else {\n\t\t\t\t\treturn this.sendReply(`Usage: /tour ${cmd} `);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (target.toLowerCase() === 'infinity' || target === '0') target = 'off';\n\t\t\tconst timeout = target.toLowerCase() === 'off' ? Infinity : Number(target) * 60 * 1000;\n\t\t\tif (timeout <= 0 || (timeout !== Infinity && timeout > Chat.MAX_TIMEOUT_DURATION)) {\n\t\t\t\treturn this.errorReply(`The automatic disqualification timer must be set to a positive number.`);\n\t\t\t}\n\t\t\tif (timeout === tournament.autoDisqualifyTimeout) {\n\t\t\t\treturn this.errorReply(`The automatic tournament disqualify timer is already set to ${target} minute(s).`);\n\t\t\t}\n\t\t\tif (tournament.setAutoDisqualifyTimeout(timeout, this)) {\n\t\t\t\tthis.privateModAction(`The tournament auto disqualify timer was set to ${target} by ${user.name}`);\n\t\t\t\tthis.modlog('TOUR AUTODQ', null, timeout === Infinity ? 'off' : target);\n\t\t\t}\n\t\t},\n\t\trunautodq(target, room, user) {\n\t\t\troom = this.requireRoom();\n\t\t\tthis.checkCan('tournaments', null, room);\n\t\t\tconst tournament = this.requireGame(Tournament);\n\t\t\tif (tournament.autoDisqualifyTimeout === Infinity) {\n\t\t\t\treturn this.errorReply(\"The automatic tournament disqualify timer is not set.\");\n\t\t\t}\n\t\t\ttournament.runAutoDisqualify(this);\n\t\t\tthis.roomlog(`${user.name} used /tour runautodq`);\n\t\t},\n\t\tscout: 'setscouting',\n\t\tscouting: 'setscouting',\n\t\tsetscout: 'setscouting',\n\t\tsetscouting(target, room, user, connection, cmd) {\n\t\t\troom = this.requireRoom();\n\t\t\tthis.checkCan('tournaments', null, room);\n\t\t\tconst tournament = this.requireGame(Tournament);\n\t\t\ttarget = target.trim();\n\t\t\tif (!target) {\n\t\t\t\tif (tournament.allowScouting) {\n\t\t\t\t\treturn this.sendReply(\"This tournament allows spectating other battles while in a tournament.\");\n\t\t\t\t} else {\n\t\t\t\t\treturn this.sendReply(\"This tournament disallows spectating other battles while in a tournament.\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst option = target.toLowerCase();\n\t\t\tif (this.meansYes(option) || option === 'allow' || option === 'allowed') {\n\t\t\t\tif (tournament.allowScouting) return this.errorReply(\"Scouting for this tournament is already set to allowed.\");\n\t\t\t\ttournament.setScouting(true);\n\t\t\t\tthis.privateModAction(`The tournament was set to allow scouting by ${user.name}`);\n\t\t\t\tthis.modlog('TOUR SCOUT', null, 'allow');\n\t\t\t} else if (this.meansNo(option) || option === 'disallow' || option === 'disallowed') {\n\t\t\t\tif (!tournament.allowScouting) return this.errorReply(\"Scouting for this tournament is already disabled.\");\n\t\t\t\ttournament.setScouting(false);\n\t\t\t\tthis.privateModAction(`The tournament was set to disallow scouting by ${user.name}`);\n\t\t\t\tthis.modlog('TOUR SCOUT', null, 'disallow');\n\t\t\t} else {\n\t\t\t\treturn this.sendReply(`Usage: /tour ${cmd}`);\n\t\t\t}\n\t\t},\n\t\tmodjoin: 'setmodjoin',\n\t\tsetmodjoin(target, room, user, connection, cmd) {\n\t\t\troom = this.requireRoom();\n\t\t\tthis.checkCan('tournaments', null, room);\n\t\t\tconst tournament = this.requireGame(Tournament);\n\t\t\ttarget = target.trim();\n\t\t\tif (!target) {\n\t\t\t\tif (tournament.allowModjoin) {\n\t\t\t\t\treturn this.sendReply(\"This tournament allows players to modjoin their battles.\");\n\t\t\t\t} else {\n\t\t\t\t\treturn this.sendReply(\"This tournament does not allow players to modjoin their battles.\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst option = target.toLowerCase();\n\t\t\tif (this.meansYes(option) || option === 'allowed') {\n\t\t\t\tif (tournament.allowModjoin) return this.errorReply(\"Modjoining is already allowed for this tournament.\");\n\t\t\t\ttournament.setModjoin(true);\n\t\t\t\tthis.privateModAction(`The tournament was set to allow modjoin by ${user.name}`);\n\t\t\t\tthis.modlog('TOUR MODJOIN', null, option);\n\t\t\t} else if (this.meansNo(option) || option === 'disallowed') {\n\t\t\t\tif (!tournament.allowModjoin) return this.errorReply(\"Modjoining is already not allowed for this tournament.\");\n\t\t\t\ttournament.setModjoin(false);\n\t\t\t\tthis.privateModAction(`The tournament was set to disallow modjoin by ${user.name}`);\n\t\t\t\tthis.modlog('TOUR MODJOIN', null, option);\n\t\t\t} else {\n\t\t\t\treturn this.sendReply(`Usage: /tour ${cmd} `);\n\t\t\t}\n\t\t},\n\t\taconly: 'autoconfirmedonly',\n\t\tonlyac: 'autoconfirmedonly',\n\t\tonlyautoconfirmed: 'autoconfirmedonly',\n\t\tautoconfirmedonly(target, room, user, connection, cmd) {\n\t\t\troom = this.requireRoom();\n\t\t\tthis.checkCan('tournaments', null, room);\n\t\t\tconst tournament = this.requireGame(Tournament);\n\t\t\ttarget = target.trim();\n\t\t\tif (!target) {\n\t\t\t\treturn this.sendReply(\n\t\t\t\t\t`This tournament ${tournament.autoconfirmedOnly ? 'does not allow' : 'allows'} non-autoconfirmed users to join a tournament.`\n\t\t\t\t);\n\t\t\t}\n\t\t\tconst value = this.meansYes(target) ? true : this.meansNo(target) ? false : null;\n\t\t\ttarget = value ? 'ON' : 'OFF';\n\t\t\tif (value === null || !toID(target)) {\n\t\t\t\treturn this.parse(`/help tour`);\n\t\t\t}\n\t\t\tif (tournament.autoconfirmedOnly === value) {\n\t\t\t\treturn this.errorReply(`This tournament is already set to ${value ? 'disallow' : 'allow'} non-autoconfirmed users.`);\n\t\t\t}\n\t\t\ttournament.setAutoconfirmedOnly(value);\n\t\t\tthis.privateModAction(`${user.name} set this tournament to ${value ? 'disallow' : 'allow'} non-autoconfirmed users.`);\n\t\t\tthis.modlog('TOUR AUTOCONFIRMEDONLY', null, target);\n\t\t},\n\t\tforcepublic(target, room, user, connection, cmd) {\n\t\t\troom = this.requireRoom();\n\t\t\tthis.checkCan('tournaments', null, room);\n\t\t\tconst tournament = this.requireGame(Tournament);\n\t\t\ttarget = target.trim();\n\t\t\tconst option = target || 'on';\n\t\t\tif (this.meansYes(option)) {\n\t\t\t\tif (tournament.forcePublic) {\n\t\t\t\t\tthrow new Chat.ErrorMessage(`Tournament battles are already being forced public.`);\n\t\t\t\t}\n\t\t\t\ttournament.setForcePublic(true);\n\t\t\t\tthis.privateModAction(`Tournament public battles were turned ON by ${user.name}`);\n\t\t\t\tthis.modlog('TOUR FORCEPUBLIC', null, 'ON');\n\t\t\t} else if (this.meansNo(option) || option === 'stop') {\n\t\t\t\tif (!tournament.forcePublic) {\n\t\t\t\t\tthrow new Chat.ErrorMessage(`Tournament battles are not being forced public.`);\n\t\t\t\t}\n\t\t\t\ttournament.setForcePublic(false);\n\t\t\t\tthis.privateModAction(`Tournament public battles were turned OFF by ${user.name}`);\n\t\t\t\tthis.modlog('TOUR FORCEPUBLIC', null, 'OFF');\n\t\t\t} else {\n\t\t\t\treturn this.sendReply(`Usage: /tour ${cmd} `);\n\t\t\t}\n\t\t},\n\t\tforcetimer(target, room, user, connection, cmd) {\n\t\t\troom = this.requireRoom();\n\t\t\tthis.checkCan('tournaments', null, room);\n\t\t\tconst tournament = this.requireGame(Tournament);\n\t\t\ttarget = target.trim();\n\t\t\tconst option = target ? target.toLowerCase() : 'on';\n\t\t\tif (this.meansYes(option)) {\n\t\t\t\ttournament.setForceTimer(true);\n\t\t\t\tfor (const player of tournament.players) {\n\t\t\t\t\tplayer.inProgressMatch?.room.game?.startTimer();\n\t\t\t\t}\n\t\t\t\tthis.privateModAction(`The timer was turned on for the tournament by ${user.name}`);\n\t\t\t\tthis.modlog('TOUR FORCETIMER', null, 'ON');\n\t\t\t} else if (this.meansNo(option) || option === 'stop') {\n\t\t\t\ttournament.setForceTimer(false);\n\t\t\t\tthis.privateModAction(`The timer was turned off for the tournament by ${user.name}`);\n\t\t\t\tthis.modlog('TOUR FORCETIMER', null, 'OFF');\n\t\t\t} else {\n\t\t\t\treturn this.sendReply(`Usage: /tour ${cmd} `);\n\t\t\t}\n\t\t},\n\t\tsettings: {\n\t\t\tmodjoin(target, room, user) {\n\t\t\t\troom = this.requireRoom();\n\t\t\t\tthis.checkCan('declare', null, room);\n\t\t\t\tif (!target || (!this.meansYes(target) && !this.meansNo(target))) {\n\t\t\t\t\treturn this.parse(`/help tour settings`);\n\t\t\t\t}\n\t\t\t\tconst tour = room.getGame(Tournament);\n\t\t\t\troom.settings.tournaments ||= {};\n\t\t\t\tif (this.meansYes(target)) {\n\t\t\t\t\tif (room.settings.tournaments.allowModjoin) {\n\t\t\t\t\t\tthrow new Chat.ErrorMessage(`Modjoin is already enabled for every tournament.`);\n\t\t\t\t\t}\n\t\t\t\t\tif (tour && !tour.allowModjoin) this.parse(`/tour modjoin allow`);\n\t\t\t\t\troom.settings.tournaments.allowModjoin = true;\n\t\t\t\t\troom.saveSettings();\n\t\t\t\t\tthis.privateModAction(`Modjoin was enabled for every tournament by ${user.name}`);\n\t\t\t\t\tthis.modlog('TOUR SETTINGS', null, 'modjoin: ALLOW');\n\t\t\t\t} else {\n\t\t\t\t\tif (!room.settings.tournaments.allowModjoin) {\n\t\t\t\t\t\tthrow new Chat.ErrorMessage(`Modjoin is already disabled for every tournament.`);\n\t\t\t\t\t}\n\t\t\t\t\tif (tour?.allowModjoin) this.parse(`/tour modjoin disallow`);\n\t\t\t\t\troom.settings.tournaments.allowModjoin = false;\n\t\t\t\t\troom.saveSettings();\n\t\t\t\t\tthis.privateModAction(`Modjoin was disabled for every tournament by ${user.name}`);\n\t\t\t\t\tthis.modlog('TOUR SETTINGS', null, 'modjoin: DISALLOW');\n\t\t\t\t}\n\t\t\t},\n\t\t\tscouting(target, room, user) {\n\t\t\t\troom = this.requireRoom();\n\t\t\t\tthis.checkCan('declare', null, room);\n\t\t\t\tif (!target || (!this.meansYes(target) && !this.meansNo(target))) return this.parse(`/help tour settings`);\n\t\t\t\tconst tour = room.getGame(Tournament);\n\t\t\t\troom.settings.tournaments ||= {};\n\t\t\t\tif (this.meansYes(target)) {\n\t\t\t\t\tif (room.settings.tournaments.allowScouting) {\n\t\t\t\t\t\tthrow new Chat.ErrorMessage(`Scouting is already enabled for every tournament.`);\n\t\t\t\t\t}\n\t\t\t\t\tif (tour && !tour.allowScouting) this.parse(`/tour scouting allow`);\n\t\t\t\t\troom.settings.tournaments.allowScouting = true;\n\t\t\t\t\troom.saveSettings();\n\t\t\t\t\tthis.privateModAction(`Scouting was enabled for every tournament by ${user.name}`);\n\t\t\t\t\tthis.modlog('TOUR SETTINGS', null, 'scouting: ALLOW');\n\t\t\t\t} else {\n\t\t\t\t\tif (!room.settings.tournaments.allowScouting) {\n\t\t\t\t\t\tthrow new Chat.ErrorMessage(`Scouting is already disabled for every tournament.`);\n\t\t\t\t\t}\n\t\t\t\t\tif (tour?.allowScouting) this.parse(`/tour scouting disallow`);\n\t\t\t\t\troom.settings.tournaments.allowScouting = false;\n\t\t\t\t\troom.saveSettings();\n\t\t\t\t\tthis.privateModAction(`Scouting was disabled for every tournament by ${user.name}`);\n\t\t\t\t\tthis.modlog('TOUR SETTINGS', null, 'scouting: DISALLOW');\n\t\t\t\t}\n\t\t\t},\n\t\t\taconly: 'autoconfirmedonly',\n\t\t\tonlyac: 'autoconfirmedonly',\n\t\t\tonlyautoconfirmed: 'autoconfirmedonly',\n\t\t\tautoconfirmedonly(target, room, user) {\n\t\t\t\troom = this.requireRoom();\n\t\t\t\tthis.checkCan('declare', null, room);\n\t\t\t\tconst tour = room.getGame(Tournament);\n\t\t\t\troom.settings.tournaments ||= {};\n\t\t\t\tconst value = this.meansYes(target) ? true : this.meansNo(target) ? false : null;\n\t\t\t\tif (!target || value === null) return this.parse(`/help tour settings`);\n\t\t\t\tif (room.settings.tournaments.autoconfirmedOnly === value) {\n\t\t\t\t\treturn this.errorReply(`All tournaments are already set to ${value ? 'disallow' : 'allow'} non-autoconfimed users.`);\n\t\t\t\t}\n\t\t\t\troom.settings.tournaments.autoconfirmedOnly = value;\n\t\t\t\troom.saveSettings();\n\t\t\t\ttarget = value ? 'ON' : 'OFF';\n\t\t\t\tthis.modlog('TOUR SETTINGS', null, `autoconfirmed only: ${target}`);\n\t\t\t\tif (tour) this.parse(`/tour autoconfirmedonly ${target}`);\n\t\t\t\tthis.privateModAction(`${user.name} set all tournaments to ${value ? 'disallow' : 'allow'} non-autoconfirmed users.`);\n\t\t\t},\n\t\t\tforcepublic(target, room, user) {\n\t\t\t\troom = this.requireRoom();\n\t\t\t\tthis.checkCan('declare', null, room);\n\t\t\t\tif (!target || (!this.meansNo(target) && !this.meansYes(target))) return this.parse(`/help tour settings`);\n\t\t\t\tconst tour = room.getGame(Tournament);\n\t\t\t\troom.settings.tournaments ||= {};\n\t\t\t\tif (this.meansNo(target)) {\n\t\t\t\t\tif (!room.settings.tournaments.forcePublic) {\n\t\t\t\t\t\tthrow new Chat.ErrorMessage(`Forced public battles are already disabled for every tournament.`);\n\t\t\t\t\t}\n\t\t\t\t\tif (tour?.forcePublic) this.parse(`/tour forcepublic off`);\n\t\t\t\t\troom.settings.tournaments.forcePublic = false;\n\t\t\t\t\troom.saveSettings();\n\t\t\t\t\tthis.privateModAction(`Forced public battles were disabled for every tournament by ${user.name}`);\n\t\t\t\t\tthis.modlog('TOUR SETTINGS', null, 'forcepublic: DISABLE');\n\t\t\t\t} else {\n\t\t\t\t\tif (room.settings.tournaments.forcePublic) {\n\t\t\t\t\t\tthrow new Chat.ErrorMessage(`Forced public battles are already enabled for every tournament.`);\n\t\t\t\t\t}\n\t\t\t\t\tif (tour && !tour.forcePublic) this.parse(`/tour forcepublic on`);\n\t\t\t\t\troom.settings.tournaments.forcePublic = true;\n\t\t\t\t\troom.saveSettings();\n\t\t\t\t\tthis.privateModAction(`Forced public battles were enabled for every tournament by ${user.name}`);\n\t\t\t\t\tthis.modlog('TOUR SETTINGS', null, 'forcepublic: ENABLE');\n\t\t\t\t}\n\t\t\t},\n\t\t\tforcetimer(target, room, user) {\n\t\t\t\troom = this.requireRoom();\n\t\t\t\tthis.checkCan('declare', null, room);\n\t\t\t\tif (!target || (!this.meansNo(target) && !this.meansYes(target))) return this.parse(`/help tour settings`);\n\t\t\t\tconst tour = room.getGame(Tournament);\n\t\t\t\troom.settings.tournaments ||= {};\n\t\t\t\tif (this.meansNo(target)) {\n\t\t\t\t\tif (!room.settings.tournaments.forceTimer) {\n\t\t\t\t\t\tthrow new Chat.ErrorMessage(`Forced timer is already disabled for every tournament.`);\n\t\t\t\t\t}\n\t\t\t\t\tif (tour?.forceTimer) this.parse(`/tour forcetimer off`);\n\t\t\t\t\troom.settings.tournaments.forceTimer = false;\n\t\t\t\t\troom.saveSettings();\n\t\t\t\t\tthis.privateModAction(`Forced timer was disabled for every tournament by ${user.name}`);\n\t\t\t\t\tthis.modlog('TOUR SETTINGS', null, 'forcetimer: DISABLE');\n\t\t\t\t} else {\n\t\t\t\t\tif (room.settings.tournaments.forceTimer) {\n\t\t\t\t\t\tthrow new Chat.ErrorMessage(`Forced timer is already enabled for every tournament.`);\n\t\t\t\t\t}\n\t\t\t\t\tif (tour && !tour.forceTimer) this.parse(`/tour forcetimer on`);\n\t\t\t\t\troom.settings.tournaments.forceTimer = true;\n\t\t\t\t\troom.saveSettings();\n\t\t\t\t\tthis.privateModAction(`Forced timer was enabled for every tournament by ${user.name}`);\n\t\t\t\t\tthis.modlog('TOUR SETTINGS', null, 'forcetimer: ENABLE');\n\t\t\t\t}\n\t\t\t},\n\t\t\tautostart(target, room, user) {\n\t\t\t\troom = this.requireRoom();\n\t\t\t\tthis.checkCan('declare', null, room);\n\t\t\t\tconst num = Number(target);\n\t\t\t\tif (!target || (!this.meansYes(target) && !this.meansNo(target) && isNaN(num))) {\n\t\t\t\t\treturn this.parse(`/help tour settings`);\n\t\t\t\t}\n\t\t\t\tconst tour = room.getGame(Tournament);\n\t\t\t\troom.settings.tournaments ||= {};\n\t\t\t\tif (this.meansNo(target)) {\n\t\t\t\t\tif (!room.settings.tournaments.autostart) {\n\t\t\t\t\t\tthrow new Chat.ErrorMessage(`Autostart is already disabled for every tournament.`);\n\t\t\t\t\t}\n\t\t\t\t\tif (tour && !tour.isTournamentStarted && tour.autoDisqualifyTimeout !== Infinity) {\n\t\t\t\t\t\tthis.parse(`/tour setautojoin off`);\n\t\t\t\t\t}\n\t\t\t\t\troom.settings.tournaments.autostart = false;\n\t\t\t\t\troom.saveSettings();\n\t\t\t\t\tthis.privateModAction(`Autostart was disabled for every tournament by ${user.name}`);\n\t\t\t\t\tthis.modlog('TOUR SETTINGS', null, 'autostart: DISABLE');\n\t\t\t\t} else if (this.meansYes(target) && target !== '1') {\n\t\t\t\t\tif (room.settings.tournaments.autostart === true) {\n\t\t\t\t\t\tthrow new Chat.ErrorMessage(`Autostart for every tournament is already set to true.`);\n\t\t\t\t\t}\n\t\t\t\t\troom.settings.tournaments.autostart = true;\n\t\t\t\t\tif (tour && !tour.isTournamentStarted && tour.playerCap) this.parse(`/tour setautostart on`);\n\t\t\t\t\troom.saveSettings();\n\t\t\t\t\tthis.privateModAction(`Autostart was set to true for every tournament by ${user.name}`);\n\t\t\t\t\tthis.modlog('TOUR SETTINGS', null, `autostart: ON`);\n\t\t\t\t} else if (!isNaN(num)) {\n\t\t\t\t\tconst timeout = num * 60 * 1000;\n\t\t\t\t\tif (timeout < 0.5 * 60 * 1000 || timeout > Chat.MAX_TIMEOUT_DURATION) {\n\t\t\t\t\t\tthrow new Chat.ErrorMessage(`The autostart must be set to at least 0.5.`);\n\t\t\t\t\t}\n\t\t\t\t\tif (room.settings.tournaments.autostart === timeout) {\n\t\t\t\t\t\tthrow new Chat.ErrorMessage(`Autostart for every tournament is already set to ${num}.`);\n\t\t\t\t\t}\n\t\t\t\t\troom.settings.tournaments.autostart = timeout;\n\t\t\t\t\tif (tour && !tour.isTournamentStarted && tour.autoStartTimeout === Infinity) {\n\t\t\t\t\t\tthis.parse(`/tour setautostart ${num}`);\n\t\t\t\t\t}\n\t\t\t\t\troom.saveSettings();\n\t\t\t\t\tthis.privateModAction(`Autostart was set to ${num} minute(s) for every tournament by ${user.name}`);\n\t\t\t\t\tthis.modlog('TOUR SETTINGS', null, `autostart: ${num} minute(s)`);\n\t\t\t\t}\n\t\t\t},\n\t\t\tautodq(target, room, user) {\n\t\t\t\troom = this.requireRoom();\n\t\t\t\tthis.checkCan('declare', null, room);\n\t\t\t\tconst num = Number(target);\n\t\t\t\tif (!target || (!this.meansNo(target) && isNaN(num))) return this.parse(`/help tour settings`);\n\t\t\t\tconst tour = room.getGame(Tournament);\n\t\t\t\troom.settings.tournaments ||= {};\n\t\t\t\tif (this.meansNo(target)) {\n\t\t\t\t\tif (!room.settings.tournaments.autodq) {\n\t\t\t\t\t\tthrow new Chat.ErrorMessage(`Automatic disqualification is already disabled for every tournament.`);\n\t\t\t\t\t}\n\t\t\t\t\tif (tour && !tour.isTournamentStarted && tour.autoDisqualifyTimeout !== Infinity) {\n\t\t\t\t\t\tthis.parse(`/tour autodq off`);\n\t\t\t\t\t}\n\t\t\t\t\tdelete room.settings.tournaments.autodq;\n\t\t\t\t\troom.saveSettings();\n\t\t\t\t\tthis.privateModAction(`Automatic disqualification was disabled for every tournament by ${user.name}`);\n\t\t\t\t\tthis.modlog('TOUR SETTINGS', null, 'autodq: DISABLE');\n\t\t\t\t} else if (!isNaN(num)) {\n\t\t\t\t\tconst timeout = num * 60 * 1000;\n\t\t\t\t\tif (timeout < 0.5 * 60 * 1000 || timeout > Chat.MAX_TIMEOUT_DURATION) {\n\t\t\t\t\t\tthrow new Chat.ErrorMessage(`The autodq must be set to a number greater than 1.`);\n\t\t\t\t\t}\n\t\t\t\t\tif (room.settings.tournaments.autodq === timeout) {\n\t\t\t\t\t\tthrow new Chat.ErrorMessage(`Automatic disqualification for every tournament is already set to ${num}.`);\n\t\t\t\t\t}\n\t\t\t\t\troom.settings.tournaments.autodq = timeout;\n\t\t\t\t\tif (tour?.autoDisqualifyTimeout === Infinity) {\n\t\t\t\t\t\tthis.parse(`/tour autodq ${num}`);\n\t\t\t\t\t}\n\t\t\t\t\troom.saveSettings();\n\t\t\t\t\tthis.privateModAction(`Automatic disqualification was set to ${num} minute(s) for every tournament by ${user.name}`);\n\t\t\t\t\tthis.modlog('TOUR SETTINGS', null, `autodq: ${num} minute(s)`);\n\t\t\t\t}\n\t\t\t},\n\t\t\tplayercap(target, room, user) {\n\t\t\t\troom = this.requireRoom();\n\t\t\t\tthis.checkCan('declare', null, room);\n\t\t\t\tconst num = parseInt(target);\n\t\t\t\tif (!target || (!this.meansNo(target) && isNaN(num))) return this.parse(`/help tour settings`);\n\t\t\t\tconst tour = room.getGame(Tournament);\n\t\t\t\troom.settings.tournaments ||= {};\n\t\t\t\tif (this.meansNo(target)) {\n\t\t\t\t\tif (!room.settings.tournaments.playerCap) {\n\t\t\t\t\t\tthrow new Chat.ErrorMessage(`Player Cap is already removed for every tournament.`);\n\t\t\t\t\t}\n\t\t\t\t\tif (tour && !tour.isTournamentStarted && tour.playerCap) {\n\t\t\t\t\t\tthis.parse(`/tour setplayercap off`);\n\t\t\t\t\t}\n\t\t\t\t\tdelete room.settings.tournaments.playerCap;\n\t\t\t\t\troom.saveSettings();\n\t\t\t\t\tthis.privateModAction(`Player Cap was removed for every tournament by ${user.name}`);\n\t\t\t\t\tthis.modlog('TOUR SETTINGS', null, 'playercap: REMOVE');\n\t\t\t\t} else if (!isNaN(num)) {\n\t\t\t\t\tif (num < 2) {\n\t\t\t\t\t\tthrow new Chat.ErrorMessage(`The Player Cap must be at least 2.`);\n\t\t\t\t\t}\n\t\t\t\t\tif (room.settings.tournaments.playerCap === num) {\n\t\t\t\t\t\tthrow new Chat.ErrorMessage(`Player Cap for every tournament is already set to ${num}.`);\n\t\t\t\t\t}\n\t\t\t\t\troom.settings.tournaments.playerCap = num;\n\t\t\t\t\tif (tour && !tour.isTournamentStarted && !tour.playerCap) {\n\t\t\t\t\t\tthis.parse(`/tour setplayercap ${num}`);\n\t\t\t\t\t\tif (room.settings.tournaments.autostart === true) this.parse(`/tour autostart on`);\n\t\t\t\t\t}\n\t\t\t\t\troom.saveSettings();\n\t\t\t\t\tthis.privateModAction(`Player Cap was set to ${num} for every tournament by ${user.name}`);\n\t\t\t\t\tthis.modlog('TOUR SETTINGS', null, `playercap: ${num}`);\n\t\t\t\t\tif (Config.tourdefaultplayercap && room.settings.tournaments.playerCap > Config.tourdefaultplayercap) {\n\t\t\t\t\t\tMonitor.log(`[TourMonitor] Room ${room.roomid} setting cap for every tour over default cap (${room.settings.tournaments.playerCap})`);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn this.sendReply(`Usage: ${this.cmdToken}${this.fullCmd} `);\n\t\t\t\t}\n\t\t\t},\n\t\t\trecenttours(target, room, user) {\n\t\t\t\troom = this.requireRoom();\n\t\t\t\tthis.checkCan('declare', null, room);\n\t\t\t\tlet num = parseInt(target);\n\t\t\t\tconst forcedelete = toID(target) === 'forcedelete';\n\t\t\t\tif (this.meansNo(target) || forcedelete) num = 0;\n\t\t\t\tif (isNaN(num) || num > 15 || num < 0) {\n\t\t\t\t\treturn this.parse(`/help tour settings`);\n\t\t\t\t}\n\t\t\t\troom.settings.tournaments ||= {};\n\t\t\t\tif (num >= 1) {\n\t\t\t\t\tif (room.settings.tournaments.recentToursLength === num) {\n\t\t\t\t\t\tthrow new Chat.ErrorMessage(`Number of recent tournaments to record is already set to ${num}.`);\n\t\t\t\t\t}\n\t\t\t\t\troom.settings.tournaments.recentToursLength = num;\n\t\t\t\t\tif (room.settings.tournaments.recentTours) {\n\t\t\t\t\t\twhile (room.settings.tournaments.recentTours.length > num) {\n\t\t\t\t\t\t\troom.settings.tournaments.recentTours.pop();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\troom.saveSettings();\n\t\t\t\t\tthis.privateModAction(`Number of recent tournaments to record was set to ${num} by ${user.name}.`);\n\t\t\t\t\tthis.modlog('TOUR SETTINGS', null, `recent tours: ${num} most recent`);\n\t\t\t\t} else {\n\t\t\t\t\tif (forcedelete && room.settings.tournaments.recentTours) {\n\t\t\t\t\t\tdelete room.settings.tournaments.recentTours;\n\t\t\t\t\t\tthis.privateModAction(`Recent tournaments list was deleted by ${user.name}.`);\n\t\t\t\t\t\tthis.modlog('TOUR SETTINGS', null, `recent tours: delete`);\n\t\t\t\t\t}\n\t\t\t\t\tif (!room.settings.tournaments.recentToursLength) {\n\t\t\t\t\t\tthrow new Chat.ErrorMessage(`Number of recent tournaments to record is already disabled.`);\n\t\t\t\t\t}\n\t\t\t\t\tdelete room.settings.tournaments.recentToursLength;\n\t\t\t\t\troom.saveSettings();\n\t\t\t\t\tthis.privateModAction(`Number of recent tournaments to record was turned off by ${user.name}.`);\n\t\t\t\t\tthis.modlog('TOUR SETTINGS', null, `recent tours: off`);\n\t\t\t\t}\n\t\t\t},\n\t\t\tblockrecents(target, room, user) {\n\t\t\t\troom = this.requireRoom();\n\t\t\t\tthis.checkCan('declare', null, room);\n\t\t\t\ttarget = toID(target);\n\t\t\t\tif (!target || (!this.meansYes(target) && !this.meansNo(target))) {\n\t\t\t\t\tif (room.settings.tournaments?.blockRecents) {\n\t\t\t\t\t\tthis.sendReply(`Recent tournaments are currently ${room.settings.tournaments.blockRecents ? '' : 'NOT '} blocked from being made.`);\n\t\t\t\t\t}\n\t\t\t\t\treturn this.parse(`/help tour settings`);\n\t\t\t\t}\n\t\t\t\troom.settings.tournaments ||= {};\n\t\t\t\tif (this.meansYes(target)) {\n\t\t\t\t\tif (room.settings.tournaments.blockRecents) {\n\t\t\t\t\t\tthrow new Chat.ErrorMessage(`Recent tournaments are already blocked from being made.`);\n\t\t\t\t\t}\n\t\t\t\t\troom.settings.tournaments.blockRecents = true;\n\t\t\t\t\troom.saveSettings();\n\t\t\t\t\tthis.privateModAction(`Recent tournaments were blocked from being made by ${user.name}.`);\n\t\t\t\t\tthis.modlog('TOUR SETTINGS', null, `recent tour block: on`);\n\t\t\t\t} else {\n\t\t\t\t\tif (!room.settings.tournaments.blockRecents) {\n\t\t\t\t\t\tthrow new Chat.ErrorMessage(`Recent tournaments are already allowed to be remade.`);\n\t\t\t\t\t}\n\t\t\t\t\tdelete room.settings.tournaments.blockRecents;\n\t\t\t\t\troom.saveSettings();\n\t\t\t\t\tthis.privateModAction(`Recent tournaments were allowed to be remade by ${user.name}.`);\n\t\t\t\t\tthis.modlog('TOUR SETTINGS', null, `recent tour block: off`);\n\t\t\t\t}\n\t\t\t},\n\t\t\t'': 'help',\n\t\t\thelp() {\n\t\t\t\tthis.parse(`${this.cmdToken}help tour settings`);\n\t\t\t},\n\t\t},\n\t},\n\ttournamenthelp(target) {\n\t\tif (!this.runBroadcast()) return;\n\t\tif (target.endsWith('settings')) {\n\t\t\treturn this.sendReplyBox(\n\t\t\t\t`/tour settings autodq <minutes|off> - Sets the automatic disqualification timeout for every tournament.
` +\n\t\t\t\t`/tour settings autostart <on|minutes|off> - Sets the automatic start timeout for every tournament.
` +\n\t\t\t\t`/tour settings forcepublic <on|off> - Specifies whether users can hide their battles for every tournament.
` +\n\t\t\t\t`/tour settings forcetimer <on|off> - Specifies whether users can toggle the timer for every tournament.
` +\n\t\t\t\t`/tour settings modjoin <on|off> - Specifies whether users can modjoin their battles for every tournament.
`\t+\n\t\t\t\t`/tour settings autoconfirmedonly<on|off> - Set requirement for signups for this tournament. If this is on, only autoconfirmed users can join a tournament.
`\t+\n\t\t\t\t`/tour settings playercap <number> - Sets the playercap for every tournament.
` +\n\t\t\t\t`/tour settings scouting <on|off> - Specifies whether users can spectate other participants for every tournament.
` +\n\t\t\t\t`/tour settings recenttours <number|off|forcedelete> - Specifies the amount of recent tournaments to list in /recenttours.
` +\n\t\t\t\t`/tour settings blockrecents <on|off> - Toggles blocking tours in /recenttours from being made.
` +\n\t\t\t\t`Requires: # ~`,\n\t\t\t);\n\t\t}\n\n\t\tthis.sendReplyBox(\n\t\t\t`Tournament Commands
` +\n\t\t\t`- create/new <format>, <type>, [ <comma-separated arguments>]: Creates a new tournament in the current room.
` +\n\t\t\t`- rules <comma-separated arguments>: Sets the custom rules for the tournament before it has started. Custom rules help/list
` +\n\t\t\t`- end/stop/delete: Forcibly ends the tournament in the current room.
` +\n\t\t\t`- begin/start: Starts the tournament in the current room.

` +\n\t\t\t`
Configuration Commands` +\n\t\t\t`- settype <type> [, <comma-separated arguments>]: Modifies the type of tournament after it's been created, but before it has started.
` +\n\t\t\t`- cap/playercap <cap>: Sets the player cap of the tournament before it has started.
` +\n\t\t\t`- viewrules/viewbanlist: Shows the custom rules for the tournament.
` +\n\t\t\t`- clearrules/clearbanlist: Clears the custom rules for the tournament before it has started.
` +\n\t\t\t`- name <name>: Sets a custom name for the tournament.
` +\n\t\t\t`- clearname: Clears the custom name of the tournament.
` +\n\t\t\t`- autostart/setautostart <on|minutes|off>: Sets the automatic start timeout.
` +\n\t\t\t`- dq/disqualify <user>: Disqualifies a user.
` +\n\t\t\t`- autodq/setautodq <minutes|off>: Sets the automatic disqualification timeout.
` +\n\t\t\t`- runautodq: Manually run the automatic disqualifier.
` +\n\t\t\t`- autoconfirmedonly/onlyautoconfirmed/aconly/onlyac <on|off>: Set requirement for signups for this tournament. If this is on, only autoconfirmed users can join a tournament.
` +\n\t\t\t`- scouting <allow|disallow>: Specifies whether joining tournament matches while in a tournament is allowed.
` +\n\t\t\t`- modjoin <allow|disallow>: Specifies whether players can modjoin their battles.
` +\n\t\t\t`- forcetimer <on|off>: Turn on the timer for tournament battles.
` +\n\t\t\t`- forcepublic <on|off>: Forces tournament battles and their replays to be public.
` +\n\t\t\t`- getusers: Lists the users in the current tournament.
` +\n\t\t\t`- announce/announcements <on|off>: Enables/disables tournament announcements for the current room.
` +\n\t\t\t`- banuser/unbanuser <user>: Bans/unbans a user from joining tournaments in this room. Lasts 2 weeks.
` +\n\t\t\t`- sub/replace <olduser>, <newuser>: Substitutes a new user for an old one
` +\n\t\t\t`- settings: Do /help tour settings for more information
` +\n\t\t\t`
` +\n\t\t\t`
` +\n\t\t\t`You can also consult more detailed help.`\n\t\t);\n\t},\n};\n\nconst roomSettings: Chat.SettingsHandler[] = [\n\troom => ({\n\t\tlabel: \"Tournament Forced Public Battles\",\n\t\tpermission: \"editroom\",\n\t\toptions: [\n\t\t\t['on', room.settings.tournaments?.forcePublic || 'tour settings forcepublic on'],\n\t\t\t['off', !room.settings.tournaments?.forcePublic || 'tour settings forcepublic off'],\n\t\t],\n\t}),\n\troom => ({\n\t\tlabel: \"Tournament Forced Timer\",\n\t\tpermission: \"editroom\",\n\t\toptions: [\n\t\t\t['on', room.settings.tournaments?.forceTimer || 'tour settings forcetimer on'],\n\t\t\t['off', !room.settings.tournaments?.forceTimer || 'tour settings forcetimer off'],\n\t\t],\n\t}),\n\troom => ({\n\t\tlabel: \"Tournament Modjoin\",\n\t\tpermission: \"editroom\",\n\t\toptions: [\n\t\t\t['allow', room.settings.tournaments?.allowModjoin || 'tour settings modjoin allow'],\n\t\t\t['disallow', !room.settings.tournaments?.allowModjoin || 'tour settings modjoin disallow'],\n\t\t],\n\t}),\n\troom => ({\n\t\tlabel: \"Tournament Autoconfirmed Only\",\n\t\tpermission: \"editroom\",\n\t\toptions: [\n\t\t\t['on', room.settings.tournaments?.autoconfirmedOnly || 'tour settings aconly on'],\n\t\t\t['off', !room.settings.tournaments?.autoconfirmedOnly || 'tour settings aconly off'],\n\t\t],\n\t}),\n\troom => ({\n\t\tlabel: \"Tournament Scouting\",\n\t\tpermission: \"editroom\",\n\t\toptions: [\n\t\t\t['allow', room.settings.tournaments?.allowScouting || 'tour settings scouting allow'],\n\t\t\t['disallow', !room.settings.tournaments?.allowScouting || 'tour settings scouting disallow'],\n\t\t],\n\t}),\n\troom => ({\n\t\tlabel: \"Tournament Recent Tours\",\n\t\tpermission: \"editroom\",\n\t\toptions: ['off', 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15].map(\n\t\t\tsetting => (\n\t\t\t\t[\n\t\t\t\t\t`${setting}`,\n\t\t\t\t\tsetting === (room.settings.tournaments?.recentToursLength || 'off') || `tour settings recenttours ${setting}`,\n\t\t\t\t]\n\t\t\t)\n\t\t),\n\t}),\n\troom => ({\n\t\tlabel: \"Tournament Block Recent Tours\",\n\t\tpermission: \"editroom\",\n\t\toptions: [\n\t\t\t['on', room.settings.tournaments?.blockRecents || 'tour settings blockrecents on'],\n\t\t\t['off', !room.settings.tournaments?.blockRecents || 'tour settings blockrecents off'],\n\t\t],\n\t}),\n];\n\nexport const Tournaments = {\n\tTournamentGenerators,\n\tTournamentPlayer,\n\tTournament,\n\tcreateTournament,\n\tcommands,\n\troomSettings,\n};\n\nfor (const room of Rooms.rooms.values()) {\n\tconst announcements = (room.settings as any).tourAnnouncements;\n\tdelete (room.settings as any).tourAnnouncements;\n\tif (!announcements) {\n\t\troom.saveSettings();\n\t\tcontinue;\n\t}\n\tif (!room.settings.tournaments) room.settings.tournaments = {};\n\troom.settings.tournaments.announcements = announcements;\n\troom.saveSettings();\n}\n"], "mappings": ";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mCAA4B;AAC5B,mCAA2B;AAC3B,iBAAsB;AACtB,kBAAqB;AAoBrB,MAAM,kCAAkC,IAAI;AAC5C,MAAM,kCAAkC,KAAK;AAC7C,MAAM,8BAA8B,KAAK,KAAK;AAC9C,MAAM,6BAA6B,KAAK;AACxC,MAAM,oBAAoB;AAC1B,MAAM,yBAAyB;AAC/B,MAAM,mBAAmB,KAAK,KAAK,KAAK,KAAK;AAE7C,YAAY,sBAAsB;AAAA,EACjC,MAAM;AAAA,EACN,MAAM;AACP,CAAC;AAED,MAAM,uBAAuB;AAAA,EAC5B,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,aAAa;AACd;AAEA,SAAS,aAAa,OAA2B;AAChD,SAAO,MAAM,IAAI,UAAQ,KAAK,IAAI;AACnC;AAEO,MAAM,yBAAyB,MAAM,eAA2B;AAAA,EAmBtE,YAAY,MAA4B,MAAkB,KAAa;AACtE,UAAM,MAAM,MAAM,GAAG;AACrB,SAAK,mBAAmB,oBAAI,IAAI;AAChC,SAAK,SAAS;AACd,SAAK,kBAAkB;AACvB,SAAK,mBAAmB;AACxB,SAAK,iBAAiB;AACtB,SAAK,eAAe;AACpB,SAAK,uBAAuB;AAC5B,SAAK,iBAAiB;AAEtB,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,QAAQ;AACb,SAAK,QAAQ;AAAA,EACd;AACD;AAEO,MAAM,mBAAmB,MAAM,SAA2B;AAAA,EAkChE,YACC,MAAgB,QAAgB,WAChC,WAA+B,SAAkB,MAChD;AACD,UAAM,IAAI;AArCX,SAAkB,SAAS;AAsC1B,UAAM,WAAW,KAAK,MAAM;AAE5B,SAAK,QAAQ,OAAO,OAAO;AAC3B,SAAK,eAAe;AACpB,SAAK,mBAAmB,oBAAI,IAAI;AAChC,SAAK,eAAe;AACpB,SAAK,aAAa,YAAY,SAAS,SAAS,IAAI,OAAO,yBAAyB;AAEpF,SAAK,aAAa;AAClB,SAAK,aAAa;AAElB,SAAK,OAAO,QAAQ;AACpB,SAAK,cAAc,CAAC;AACpB,SAAK,YAAY;AACjB,SAAK,UAAU;AACf,SAAK,gBAAgB;AACrB,SAAK,eAAe;AACpB,SAAK,oBAAoB;AACzB,SAAK,aAAa;AAClB,SAAK,eAAe;AACpB,SAAK,cAAc;AACnB,QAAI,OAAO,wBAAwB,KAAK,YAAY,OAAO,sBAAsB;AAChF,cAAQ,IAAI,sBAAsB,KAAK,4CAA4C,KAAK,YAAY;AAAA,IACrG;AAEA,SAAK,sBAAsB;AAE3B,SAAK,uBAAuB;AAC5B,SAAK,oBAAoB;AACzB,SAAK,qBAAqB;AAC1B,SAAK,eAAe;AAEpB,SAAK,gCAAgC;AACrC,SAAK,wBAAwB,EAAE,YAAY,oBAAI,IAAI,GAAG,cAAc,oBAAI,IAAI,EAAE;AAE9E,SAAK,wBAAwB;AAC7B,SAAK,sBAAsB;AAC3B,SAAK,mBAAmB;AACxB,SAAK,iBAAiB;AAEtB,SAAK,IAAI,sBAAsB,KAAK,cAAc,UAAU,QAAQ,KAAK,YAAY,KAAK,SAAS,KAAK,aAAa,KAAK,IAAI,KAAK,QAAQ;AAC3I,UAAM,SAGF;AAAA,MACH,QAAQ,KAAK;AAAA,MACb,WAAW,UAAU;AAAA,MACrB,WAAW,KAAK;AAAA,MAChB,WAAW;AAAA,MACX,UAAU;AAAA,IACX;AACA,QAAI,KAAK,SAAS,KAAK;AAAY,aAAO,oBAAoB,KAAK;AACnE,SAAK,KAAK,sBAAsB,KAAK,UAAU,MAAM,GAAG;AACxD,SAAK,OAAO;AAAA,EACb;AAAA,EACA,UAAU;AACT,SAAK,SAAS;AAAA,EACf;AAAA,EACA,SAAS;AACR,QAAI,KAAK;AAAgB,mBAAa,KAAK,cAAc;AACzD,QAAI,KAAK;AAAqB,mBAAa,KAAK,mBAAmB;AACnE,eAAW,UAAU,KAAK,kBAAkB;AAC3C,YAAM,OAAO,MAAM,IAAI,MAAM;AAC7B,UAAI;AAAM,aAAK,OAAO;AAAA,IACvB;AACA,SAAK,SAAS;AACd,SAAK,KAAK,OAAO;AAAA,EAClB;AAAA,EACA,sBAAsB;AACrB,WAAO,KAAK,QAAQ,OAAO,YAAU,CAAC,OAAO,kBAAkB,CAAC,OAAO,YAAY;AAAA,EACpF;AAAA,EAEA,aAAa,WAAsB,QAA6B;AAC/D,QAAI,KAAK,qBAAqB;AAC7B,aAAO,UAAU,iCAAiC;AAClD;AAAA,IACD;AAEA,SAAK,YAAY;AACjB,SAAK,KAAK,KAAK,sBAAsB,KAAK,UAAU,EAAE,WAAW,UAAU,KAAK,CAAC,GAAG;AACpF,SAAK,uBAAuB;AAC5B,SAAK,OAAO;AACZ,WAAO;AAAA,EACR;AAAA,EAEA,eAAe,OAAe;AAC7B,QAAI;AACJ,QAAI;AACH,YAAM,YAAY,IAAI,QAAQ,SAAS,GAAG,KAAK,gBAAgB,OAAO;AACtE,eAAS,IAAI,QAAQ,IAAI,WAAW,IAAI;AAIxC,UAAI,OAAO,MAAM;AAChB,cAAM,eAAe,iBAAK,aAAa;AACvC,cAAM,oBAAoB,MAAM,aAAa,QAAQ,YAAY;AACjE,0BAAkB,QAAQ;AAAA,MAC3B;AACA,WAAK,aAAa;AAAA,IACnB,SAAS,GAAP;AACD,YAAM,IAAI,KAAK,aAAa,sBAAsB,EAAE,SAAS;AAAA,IAC9D;AAEA,UAAM,cAAc,OAAO;AAC3B,QAAI,CAAC,aAAa;AACjB,YAAM,IAAI,KAAK,aAAa,gBAAgB;AAAA,IAC7C;AACA,SAAK,cAAc;AACnB,QAAI,KAAK,SAAS,KAAK,YAAY;AAClC,WAAK,OAAO,KAAK,qBAAqB;AACtC,WAAK,KAAK,KAAK,sBAAsB,KAAK,UAAU,EAAE,QAAQ,KAAK,KAAK,CAAC,GAAG;AAC5E,WAAK,OAAO;AAAA,IACb;AACA,WAAO;AAAA,EACR;AAAA,EAEA,iBAAiB;AAChB,UAAM,OAAO,CAAC;AACd,UAAM,SAAS,CAAC;AAChB,UAAM,eAAe,CAAC;AACtB,UAAM,aAAa,CAAC;AACpB,UAAM,eAAe,CAAC;AACtB,eAAW,OAAO,KAAK,aAAa;AACnC,YAAM,UAAU,IAAI,OAAO,CAAC;AAC5B,UAAI,YAAY,KAAK;AACpB,eAAO,KAAK,IAAI,OAAO,CAAC,CAAC;AAAA,MAC1B,WAAW,YAAY,KAAK;AAC3B,aAAK,KAAK,IAAI,OAAO,CAAC,CAAC;AAAA,MACxB,WAAW,YAAY,KAAK;AAC3B,qBAAa,KAAK,IAAI,OAAO,CAAC,CAAC;AAAA,MAChC,WAAW,YAAY,KAAK;AAC3B,qBAAa,KAAK,IAAI,OAAO,CAAC,CAAC;AAAA,MAChC,OAAO;AACN,mBAAW,KAAK,GAAG;AAAA,MACpB;AAAA,IACD;AACA,UAAM,OAAO,CAAC;AACd,QAAI,KAAK;AAAQ,WAAK,KAAK,iBAAM,2BAA2B,KAAK,KAAK,IAAI,GAAG;AAC7E,QAAI,OAAO;AAAQ,WAAK,KAAK,iBAAM,6BAA6B,OAAO,KAAK,IAAI,GAAG;AACnF,QAAI,aAAa;AAAQ,WAAK,KAAK,iBAAM,mCAAmC,aAAa,KAAK,IAAI,GAAG;AACrG,QAAI,WAAW;AAAQ,WAAK,KAAK,iBAAM,4BAA4B,WAAW,KAAK,IAAI,GAAG;AAC1F,QAAI,aAAa;AAAQ,WAAK,KAAK,iBAAM,8BAA8B,aAAa,KAAK,IAAI,GAAG;AAChG,WAAO,KAAK,KAAK,QAAQ;AAAA,EAC1B;AAAA,EAEA,WAAW;AACV,QAAI,KAAK,qBAAqB;AAC7B,UAAI,KAAK;AAAqB,qBAAa,KAAK,mBAAmB;AACnE,iBAAW,UAAU,KAAK,SAAS;AAClC,cAAM,QAAQ,OAAO;AACrB,YAAI,OAAO;AACV,gBAAM,KAAK,OAAO;AAClB,gBAAM,KAAK,UAAU,IAAI;AACzB,gBAAM,KAAK,OAAO,wKAAwK;AAAA,QAC3L;AAAA,MACD;AAAA,IACD;AACA,SAAK,KAAK,IAAI,sBAAsB;AACpC,SAAK,OAAO;AAAA,EACb;AAAA,EAEA,UAAU,YAAkB,YAAgC;AAC3D,QAAI,CAAC;AAAY,mBAAa;AAC9B,QAAI,KAAK;AAAO;AAEhB,QAAK,CAAC,KAAK,sBAAsB,KAAK,wBACpC,KAAK,uBAAuB,KAAK,+BAAgC;AAClE,WAAK,KAAK;AAAA,QACT,oEACG,CAAC,KAAK,sBAAsB,KAAK,yBACjC,KAAK,uBAAuB,KAAK;AAAA,MAErC;AACA;AAAA,IACD;AACA,UAAM,iBAAiB,KAAK,YAAY,WAAW,EAAE;AACrD,QAAI,WAAW;AACf,QAAI,gBAAgB;AACnB,UAAI,KAAK,UAAU,KAAK,SAAS,aAAa,GAAG;AAChD,mBAAW,CAAC,eAAe,gBAAgB,CAAC,eAAe;AAAA,MAC5D,WAAW,KAAK,UAAU,KAAK,SAAS,aAAa,GAAG;AACvD,YAAI,eAAe,gBAAgB;AAClC,qBAAW,CAAC,eAAe;AAAA,QAC5B,WAAY,KAAK,WAA0B,kBAAkB;AAC5D,qBAAW,eAAe,UAAW,KAAK,UAAyB;AAAA,QACpE,WAAW,CAAC,KAAK,qBAAqB;AACrC,qBAAW;AAAA,QACZ;AAAA,MACD,OAAO;AACN,mBAAW;AAAA,MACZ;AAAA,IACD;AACA,UAAM,SAGF;AAAA,MACH,QAAQ,KAAK;AAAA,MACb,WAAW,KAAK,UAAU;AAAA,MAC1B,WAAW,KAAK;AAAA,MAChB;AAAA,MACA,aAAa,KAAK;AAAA,IACnB;AACA,QAAI,KAAK,SAAS,KAAK;AAAY,aAAO,oBAAoB,KAAK;AACnE,eAAW,OAAO,KAAK,MAAM,sBAAsB,KAAK,UAAU,MAAM,GAAG;AAC3E,QAAI,KAAK,uBAAuB,UAAU;AACzC,YAAM,UAAU;AAAA,QACf,YAAY,aAAa,KAAK,sBAAsB,WAAW,IAAI,KAAK,YAAY,WAAW,EAAE,CAAC,CAAE;AAAA,QACpG,cAAc,aAAa,KAAK,sBAAsB,aAAa,IAAI,KAAK,YAAY,WAAW,EAAE,CAAC,CAAE;AAAA,MACzG;AACA,iBAAW,OAAO,KAAK,MAAM,sBAAsB,KAAK,UAAU,OAAO,GAAG;AAE5E,YAAM,mBAAmB,KAAK,YAAY,WAAW,EAAE,EAAE;AACzD,UAAI,kBAAkB;AACrB,YAAI,iBAAiB,IAAI;AACxB,qBAAW,OAAO,KAAK,MAAM,sBAAsB,KAAK,UAAU,EAAE,aAAa,iBAAiB,GAAG,KAAK,CAAC,GAAG;AAAA,QAC/G,WAAW,iBAAiB,MAAM;AACjC,qBAAW,OAAO,KAAK,MAAM,sBAAsB,KAAK,UAAU,EAAE,YAAY,iBAAiB,KAAK,KAAK,CAAC,GAAG;AAAA,QAChH;AAAA,MACD;AAAA,IACD;AACA,eAAW,OAAO,KAAK,MAAM,uBAAuB;AAAA,EACrD;AAAA,EAEA,SAAS;AACR,QAAI,KAAK;AAAO;AAChB,QAAI,KAAK,sBAAsB;AAC9B,UAAI,KAAK,IAAI,IAAI,KAAK,oBAAoB,iCAAiC;AAC1E,YAAI,KAAK;AAAoB,uBAAa,KAAK,kBAAkB;AACjE,aAAK,qBAAqB,WAAW,MAAM;AAC1C,eAAK,qBAAqB;AAC1B,eAAK,OAAO;AAAA,QACb,GAAG,+BAA+B;AAAA,MACnC,OAAO;AACN,aAAK,oBAAoB,KAAK,IAAI;AAElC,aAAK,eAAe,KAAK,eAAe;AACxC,aAAK,uBAAuB;AAC5B,aAAK,KAAK,KAAK,sBAAsB,KAAK,UAAU,EAAE,aAAa,KAAK,aAAa,CAAC,GAAG;AAAA,MAC1F;AAAA,IACD;AAEA,QAAI,KAAK,uBAAuB,KAAK,+BAA+B;AACnE,WAAK,wBAAwB,KAAK,oBAAoB;AAEtD,WAAK,gCAAgC;AACrC,iBAAW,CAAC,QAAQ,SAAS,KAAK,KAAK,sBAAsB,YAAY;AACxE,eAAO,SAAS,sBAAsB,KAAK,UAAU,EAAE,YAAY,aAAa,SAAS,EAAE,CAAC,GAAG;AAAA,MAChG;AACA,iBAAW,CAAC,QAAQ,SAAS,KAAK,KAAK,sBAAsB,cAAc;AAC1E,eAAO,SAAS,sBAAsB,KAAK,UAAU,EAAE,cAAc,aAAa,SAAS,EAAE,CAAC,GAAG;AAAA,MAClG;AAAA,IACD;AACA,SAAK,KAAK,KAAK,uBAAuB;AAAA,EACvC;AAAA,EAEA,OAAO,YAAY,MAAY,MAAqB;AACnD,WAAO,YAAY,kBAAkB,MAAM,KAAK,IAAI,GAAG,SAAS;AAAA,EACjE;AAAA,EAEA,iBAAiB,QAAmB;AACnC,aAAS,KAAK,MAAM;AACpB,QAAI,EAAE,UAAU,KAAK;AAAc;AACnC,QAAI,KAAK,qBAAqB;AAC7B,YAAM,SAAS,KAAK,YAAY,MAAM;AACtC,UAAI,CAAC,OAAO,gBAAgB;AAC3B,aAAK,eAAe,MAAM;AAAA,MAC3B;AAAA,IACD,OAAO;AACN,WAAK,WAAW,MAAM;AAAA,IACvB;AACA,SAAK,KAAK,OAAO;AAAA,EAClB;AAAA,EAEA,QAAQ,MAAY,QAA6B;AAChD,QAAI,CAAC,KAAK,OAAO;AAChB,aAAO,UAAU,gCAAgC;AACjD;AAAA,IACD;AAEA,QAAI,KAAK,MAAM,KAAK,aAAa;AAChC,aAAO,UAAU,oCAAoC;AACrD;AAAA,IACD;AAEA,QAAI,KAAK,aAAa,KAAK,eAAe,KAAK,WAAW;AACzD,aAAO,UAAU,wBAAwB;AACzC;AAAA,IACD;AAEA,QAAI,WAAW,YAAY,KAAK,MAAM,IAAI,KAAK,YAAY,eAAe,IAAI,KAAK,KAAK,YAAY;AACnG,aAAO,UAAU,0BAA0B;AAC3C;AAAA,IACD;AAEA,SACE,KAAK,KAAK,SAAS,aAAa,qBAAqB,KAAK,sBAC3D,CAAC,KAAK,iBAAiB,CAAC,KAAK,SAC5B;AACD,WAAK,MAAM,kFAAkF;AAC7F;AAAA,IACD;AAEA,UAAM,YAAY,KAAK,MAAM;AAC7B,QAAI,YAAY,GAAG;AAClB,aAAO,WAAW,gEAAgE;AAClF;AAAA,IACD;AAEA,QAAI,CAAC,OAAO,YAAY;AACvB,iBAAW,eAAe,KAAK,SAAS;AACvC,YAAI,CAAC;AAAa;AAClB,cAAM,YAAY,MAAM,IAAI,YAAY,EAAE;AAC1C,YAAI,aAAa,UAAU,aAAa,KAAK,UAAU;AACtD,iBAAO,UAAU,uCAAuC;AACxD;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAEA,QAAI,KAAK,qBAAqB;AAC7B,aAAO,UAAU,iCAAiC;AAClD;AAAA,IACD;AAEA,UAAM,SAAS,KAAK,UAAU,IAAI;AAClC,QAAI,CAAC;AAAQ,YAAM,IAAI,MAAM,uBAAuB;AAEpD,SAAK,YAAY,KAAK,EAAE,IAAI;AAC5B,SAAK,KAAK,IAAI,oBAAoB,KAAK,MAAM;AAC7C,SAAK,OAAO,KAAK,MAAM,sCAAsC;AAC7D,SAAK,uBAAuB;AAC5B,SAAK,OAAO;AACZ,QAAI,KAAK,gBAAgB,KAAK,WAAW;AACxC,UAAI,KAAK,iBAAiB,MAAM;AAC/B,aAAK,gBAAgB,MAAM;AAAA,MAC5B,OAAO;AACN,aAAK,KAAK,IAAI,6BAA6B;AAAA,MAC5C;AAAA,IACD;AAAA,EACD;AAAA,EAEA,WAAW,MAA4B;AACtC,UAAM,MAAM,KAAK,QAAQ,SAAS,KAAK,QAAQ,KAAK,QAAQ,SAAS,CAAC,EAAE,MAAM;AAC9E,WAAO,IAAI,iBAAiB,MAAM,MAAM,GAAG;AAAA,EAC5C;AAAA,EAEA,WAAW,QAAY,QAA8B;AACpD,UAAM,SAAS,KAAK,YAAY,MAAM;AACtC,QAAI,CAAC,QAAQ;AACZ,UAAI;AAAQ,eAAO,UAAU,gCAAgC;AAC7D;AAAA,IACD;AAEA,SAAK,aAAa,MAAM;AACxB,UAAM,OAAO,MAAM,IAAI,MAAM;AAC7B,SAAK,KAAK,IAAI,qBAAqB,OAAO,KAAK,OAAO,QAAQ;AAC9D,QAAI;AAAM,WAAK,OAAO,KAAK,MAAM,uCAAuC;AACxE,SAAK,uBAAuB;AAC5B,SAAK,OAAO;AAAA,EACb;AAAA,EACA,YAAY,MAAY,iBAAuB,QAA6B;AAC3E,QAAI,CAAC,KAAK,qBAAqB;AAC9B,aAAO,UAAU,8BAA8B;AAC/C;AAAA,IACD;AACA,QAAI,EAAE,KAAK,MAAM,KAAK,cAAc;AACnC,aAAO,WAAW,GAAG,KAAK,+BAA+B;AACzD;AAAA,IACD;AACA,QAAI,CAAC,gBAAgB,OAAO;AAC3B,aAAO,WAAW,GAAG,gBAAgB,4CAA4C;AACjF;AAAA,IACD;AACA,QAAI,gBAAgB,MAAM,KAAK,aAAa;AAC3C,aAAO,WAAW,GAAG,gBAAgB,oCAAoC;AACzE;AAAA,IACD;AACA,QAAI,WAAW,YAAY,KAAK,MAAM,eAAe,KAAK,YAAY,eAAe,eAAe,KACnG,gBAAgB,YAAY;AAC5B,aAAO,WAAW,GAAG,gBAAgB,0CAA0C;AAC/E;AAAA,IACD;AACA,SAAK,KAAK,KAAK,SAAS,aAAa,qBAAqB,KAAK,sBAAsB,CAAC,KAAK,eAAe;AACzG,WAAK,MAAM,kFAAkF;AAC7F;AAAA,IACD;AAEA,QAAI,CAAC,OAAO,YAAY;AACvB,iBAAW,eAAe,KAAK,SAAS;AACvC,YAAI,CAAC;AAAa;AAClB,cAAM,YAAY,MAAM,IAAI,YAAY,EAAE;AAC1C,YAAI,aACH,UAAU,aAAa,gBAAgB,YACvC,gBAAgB,aAAa,KAAK,UAAU;AAC5C,iBAAO,WAAW,GAAG,gBAAgB,4CAA4C;AACjF;AAAA,QACD;AAAA,MACD;AAAA,IACD;AACA,QAAI,EAAE,gBAAgB,MAAM,KAAK,KAAK,QAAQ;AAC7C,aAAO,WAAW,GAAG,gBAAgB,6BAA6B,KAAK,KAAK,SAAS;AACrF;AAAA,IACD;AACA,UAAM,SAAS,KAAK,YAAY,KAAK,EAAE;AACvC,QAAI,OAAO,kBAAkB;AAC5B,WAAK,gBAAgB,MAAM,MAAM;AAAA,IAClC;AAGA,SAAK,cAAc,QAAQ,eAAe;AAG1C,QAAI,cAAc;AAClB,QAAI,OAAO,iBAAiB;AAC3B,oBAAc;AAAA,IACf,OAAO;AACN,iBAAW,KAAK,KAAK,SAAS;AAC7B,YAAI,EAAE,mBAAmB,EAAE,gBAAgB,OAAO,QAAQ;AACzD,wBAAc;AACd;AAAA,QACD;AAAA,MACD;AAAA,IACD;AACA,QAAI,aAAa,iBAAiB;AACjC,kBAAY,gBAAgB,GAAG,SAAS;AACxC,kBAAY,SAAS;AAErB,kBAAY,gBAAgB,KAAK;AAAA,QAChC,iBAAM,qCAAqC,KAAK,+CAChD;AAAA,MACD,EAAE,OAAO;AACT,kBAAY,gBAAgB,KAAK,UAAU,IAAI;AAC/C,WAAK,iBAAiB,IAAI,YAAY,gBAAgB,KAAK,MAAM;AACjE,kBAAY,kBAAkB;AAAA,IAC/B;AAEA,SAAK,gCAAgC;AACrC,SAAK,uBAAuB;AAE5B,SAAK,OAAO;AACZ,SAAK,UAAU,IAAI;AACnB,SAAK,UAAU,eAAe;AAC9B,UAAM,kBAAkB,OAAO,qBAC7B,OAAO,iBAAiB,QAAQ,OAAO,iBAAiB;AAC1D,QAAI,iBAAiB;AACpB,YAAM,gBAAgB,MAAM,SAAS,gBAAgB,EAAE;AACvD,UAAI;AAAe,aAAK,UAAU,aAAa;AAAA,IAChD;AAEA,SAAK,KAAK,IAAI,uBAAuB,KAAK,QAAQ,gBAAgB,MAAM;AACxE,WAAO;AAAA,EACR;AAAA,EAEA,iBAAiB;AAChB,QAAI;AACJ,QAAI,CAAC,KAAK,qBAAqB;AAC9B,aAAO,KAAK,UAAU,sBAAsB,KAAK,OAAO;AAAA,IACzD,OAAO;AACN,aAAO,KAAK,UAAU,eAAe;AAAA,IACtC;AACA,QAAI,KAAK,SAAS,QAAQ;AACzB,UAAI,CAAC,KAAK,UAAU;AACnB,aAAK,QAAQ,aAAa,KAAK,QAAQ,KAAK,CAAC;AAC7C,eAAO;AAAA,MACR;AACA,YAAM,QAAQ,CAAC,KAAK,QAAQ;AAC5B,aAAO,MAAM,SAAS,GAAG;AACxB,cAAM,OAAO,MAAM,MAAM;AAEzB,YAAI,KAAK,UAAU,aAAa;AAC/B,gBAAM,mBAAmB,KAAK,SAAS,CAAC,EAAE,KAAK;AAC/C,cAAI,oBAAoB,KAAK,SAAS,CAAC,EAAE,SAAS,iBAAiB,IAAI;AACtE,iBAAK,QAAQ;AAAA,UACd;AAEA,gBAAM,kBAAkB,KAAK,SAAS,CAAC,EAAE,KAAK;AAC9C,cAAI,mBAAmB,KAAK,SAAS,CAAC,EAAE,SAAS,gBAAgB,IAAI;AACpE,iBAAK,QAAQ;AACb,iBAAK,OAAO,gBAAgB,KAAK;AAAA,UAClC;AAAA,QACD;AAEA,YAAI,KAAK,QAAQ,OAAO,KAAK,SAAS,UAAU;AAC/C,eAAK,OAAO,KAAK,KAAK;AAAA,QACvB;AAEA,YAAI,KAAK,UAAU;AAClB,qBAAW,SAAS,KAAK,UAAU;AAClC,kBAAM,KAAK,KAAK;AAAA,UACjB;AAAA,QACD;AAAA,MACD;AAAA,IACD,WAAW,KAAK,SAAS,SAAS;AACjC,UAAI,KAAK,qBAAqB;AAC7B,mBAAW,CAAC,GAAG,GAAG,KAAK,KAAK,cAAc,QAAQ,GAAG;AACpD,gBAAM,mBAAmB,KAAK,aAAa,KAAK,CAAC,EAAE;AACnD,gBAAM,kBAAkB,KAAK,aAAa,KAAK,CAAC,EAAE;AAClD,cAAI,oBAAoB,iBAAiB;AACxC,uBAAW,CAAC,GAAG,IAAI,KAAK,IAAI,QAAQ,GAAG;AACtC,kBAAI,CAAC;AAAM;AAEX,kBAAI,oBAAoB,KAAK,aAAa,KAAK,CAAC,MAAM,iBAAiB,IAAI;AAC1E,qBAAK,QAAQ;AAAA,cACd;AAEA,kBAAI,mBAAmB,KAAK,aAAa,KAAK,CAAC,MAAM,gBAAgB,IAAI;AACxE,qBAAK,QAAQ;AACb,qBAAK,OAAO,gBAAgB,KAAK;AAAA,cAClC;AAAA,YACD;AAAA,UACD;AAAA,QACD;AAAA,MACD;AACA,WAAK,aAAa,OAAO,aAAa,KAAK,aAAa,IAAI;AAC5D,WAAK,aAAa,OAAO,aAAa,KAAK,aAAa,IAAI;AAAA,IAC7D;AACA,WAAO;AAAA,EACR;AAAA,EAEA,gBAAgB,QAA6B,aAAuB;AACnE,QAAI,KAAK,qBAAqB;AAC7B,aAAO,UAAU,kCAAkC;AACnD,aAAO;AAAA,IACR;AAEA,QAAI,KAAK,QAAQ,SAAS,GAAG;AAC5B,UAAI,aAAa;AAChB,aAAK,KAAK,KAAK,kCAAkC;AACjD,aAAK,SAAS;AACd,aAAK,KAAK,OAAO;AACjB,eAAO,OAAO,UAAU;AAAA,MACzB,OAAO;AACN,eAAO,UAAU,kCAAkC;AAAA,MACpD;AACA,aAAO;AAAA,IACR;AAEA,SAAK,UAAU,cAAc,KAAK,OAAO;AAEzC,UAAM,MAAM,KAAK,IAAI;AACrB,eAAW,QAAQ,KAAK,SAAS;AAChC,WAAK,iBAAiB;AAAA,IACvB;AAEA,SAAK,sBAAsB;AAC3B,QAAI,KAAK;AAAgB,mBAAa,KAAK,cAAc;AACzD,QAAI,KAAK,0BAA0B,UAAU;AAC5C,WAAK,sBAAsB,WAAW,MAAM,KAAK,kBAAkB,GAAG,KAAK,qBAAqB;AAAA,IACjG;AACA,SAAK,uBAAuB;AAC5B,SAAK,KAAK,IAAI,qBAAqB,KAAK,QAAQ,QAAQ;AACxD,WAAO,OAAO,cAAc,MAAM,GAAG,KAAK,QAAQ,gBAAgB;AAClE,SAAK,KAAK,KAAK,uCAAuC;AACtD,SAAK,OAAO;AACZ,WAAO;AAAA,EACR;AAAA,EACA,sBAAsB;AACrB,UAAM,UAAU,KAAK,UAAU,oBAAoB;AACnD,QAAI,OAAO,YAAY;AAAU,YAAM,IAAI,MAAM,qCAAqC,SAAS;AAE/F,UAAM,aAAa,oBAAI,IAA0C;AACjE,UAAM,eAAe,oBAAI,IAA0C;AACnE,UAAM,sBAAsB,oBAAI,IAA+B;AAE/D,eAAW,QAAQ,KAAK,SAAS;AAChC,iBAAW,IAAI,MAAM,CAAC,CAAC;AACvB,mBAAa,IAAI,MAAM,CAAC,CAAC;AAEzB,UAAI,oBAAoB;AACxB,YAAM,mBAAmB,KAAK;AAC9B,UAAI,iBAAiB,MAAM;AAC1B,4BAAoB;AACpB,yBAAiB,MAAM;AAAA,MACxB;AACA,0BAAoB,IAAI,MAAM,iBAAiB;AAAA,IAChD;AAEA,eAAW,SAAS,SAAS;AAC5B,iBAAW,IAAI,MAAM,CAAC,CAAC,EAAG,KAAK,MAAM,CAAC,CAAC;AACvC,mBAAa,IAAI,MAAM,CAAC,CAAC,EAAG,KAAK,MAAM,CAAC,CAAC;AAEzC,YAAM,CAAC,EAAE,iBAAiB,IAAI,MAAM,CAAC,CAAC;AAAA,IACvC;AAEA,UAAM,MAAM,KAAK,IAAI;AACrB,eAAW,UAAU,KAAK,SAAS;AAClC,UAAI,oBAAoB,IAAI,MAAM;AAAG;AAErC,UAAI,OAAO,iBAAiB;AAAM,eAAO,iBAAiB;AAAA,IAC3D;AAEA,WAAO;AAAA,MACN;AAAA,MACA;AAAA,IACD;AAAA,EACD;AAAA,EAEA,eAAe,QAAY,SAAqC,MAAM,SAAwB,MAAM,WAAW,OAAO;AACrH,UAAM,OAAO,MAAM,IAAI,MAAM;AAC7B,QAAI;AACJ,QAAI,QAAQ;AACX,kBAAY,SAAO,OAAO,UAAU,GAAG;AAAA,IACxC,WAAW,MAAM;AAChB,kBAAY,SAAO,KAAK,OAAO,KAAK,QAAQ,GAAG;AAAA,IAChD,OAAO;AACN,kBAAY,MAAM;AAAA,MAAC;AAAA,IACpB;AACA,QAAI,CAAC,KAAK,qBAAqB;AAC9B,gBAAU,8BAA8B;AACxC,aAAO;AAAA,IACR;AAEA,QAAI,EAAE,UAAU,KAAK,cAAc;AAClC,gBAAU,kCAAkC,QAAQ;AACpD,aAAO;AAAA,IACR;AAEA,UAAM,SAAS,KAAK,YAAY,MAAM;AACtC,QAAI,OAAO,gBAAgB;AAC1B,gBAAU,yCAAyC,QAAQ;AAC3D,aAAO;AAAA,IACR;AAEA,WAAO,iBAAiB;AAExB,UAAM,QAAQ,KAAK,UAAU,eAAe,MAAM;AAClD,QAAI,OAAO;AACV,gBAAU,qBAAqB,OAAO;AACtC,aAAO;AAAA,IACR;AAEA,WAAO,SAAS;AAEhB,UAAM,YAAY,OAAO;AACzB,QAAI,WAAW;AACd,aAAO,mBAAmB;AAC1B,UAAI,UAAU,IAAI;AACjB,kBAAU,GAAG,SAAS;AACtB,kBAAU,GAAG,mBAAmB;AAChC,kBAAU,GAAG,SAAS,wCAAwC;AAAA,MAC/D,WAAW,UAAU,MAAM;AAC1B,kBAAU,KAAK,SAAS;AACxB,kBAAU,KAAK,mBAAmB;AAClC,kBAAU,KAAK,SAAS,yCAAyC;AAAA,MAClE;AAAA,IACD;AAEA,UAAM,YAAY,OAAO;AACzB,QAAI,WAAW;AACd,gBAAU,GAAG,SAAS;AACtB,aAAO,kBAAkB;AACzB,gBAAU,KAAK,UAAU,IAAI;AAC7B,WAAK,iBAAiB,IAAI,UAAU,KAAK,MAAM;AAC/C,gBAAU,KAAK,MAAM,UAAU,OAAO,IAAI;AAAA,IAC3C;AAEA,QAAI,UAAU;AACd,eAAW,cAAc,KAAK,SAAS;AACtC,YAAM,QAAQ,WAAW;AACzB,UAAI,SAAS,MAAM,OAAO;AAAQ,kBAAU;AAAA,IAC7C;AACA,QAAI,SAAS;AACZ,cAAQ,SAAS;AACjB,YAAM,YAAY,QAAQ,gBAAiB;AAC3C,gBAAU,UAAU,IAAI;AACxB,WAAK,iBAAiB,IAAI,UAAU,MAAM;AAC1C,UAAI,UAAU;AAAM,kBAAU,KAAK,UAAU,OAAO,EAAE;AACtD,cAAQ,kBAAkB;AAAA,IAC3B;AAEA,QAAI,UAAU;AACb,WAAK,KAAK,IAAI,qBAAqB,OAAO,MAAM;AAAA,IACjD,OAAO;AACN,WAAK,KAAK,IAAI,0BAA0B,OAAO,MAAM;AAAA,IACtD;AACA,QAAI,MAAM;AACT,WAAK,OAAO,KAAK,MAAM,uCAAuC;AAC9D,WAAK,MAAM,4DAA4D,KAAK,KAAK,QAAQ,SAAS;AAAA;AAAA,EAAQ,WAAW,KAAK;AAAA,IAC3H;AACA,SAAK,uBAAuB;AAC5B,SAAK,gCAAgC;AAErC,QAAI,KAAK,UAAU,kBAAkB,GAAG;AACvC,WAAK,gBAAgB;AAAA,IACtB,OAAO;AACN,WAAK,OAAO;AAAA,IACb;AAEA,WAAO;AAAA,EACR;AAAA,EAEA,oBAAoB,SAAiB,QAA6B;AACjE,QAAI,KAAK,qBAAqB;AAC7B,aAAO,UAAU,kCAAkC;AACnD,aAAO;AAAA,IACR;AACA,QAAI,UAAU,8BAA8B,MAAM,OAAO,GAAG;AAC3D,aAAO,UAAU,2CAA2C;AAC5D,aAAO;AAAA,IACR;AAEA,QAAI,KAAK;AAAgB,mBAAa,KAAK,cAAc;AACzD,QAAI,YAAY,UAAU;AACzB,WAAK,KAAK,IAAI,2BAA2B;AAAA,IAC1C,OAAO;AACN,WAAK,iBAAiB,WAAW,MAAM,KAAK,gBAAgB,QAAQ,IAAI,GAAG,OAAO;AAClF,WAAK,KAAK,IAAI,4BAA4B,SAAS;AAAA,IACpD;AACA,SAAK,mBAAmB;AAExB,WAAO;AAAA,EACR;AAAA,EAEA,yBAAyB,SAAiB,QAA6B;AACtE,QACC,MAAM,OAAO,KAAK,UAAU,mCAC3B,UAAU,+BAA+B,YAAY,UACrD;AACD,aAAO,UAAU,gDAAgD;AACjE,aAAO;AAAA,IACR;AAEA,SAAK,wBAAwB;AAC7B,QAAI,KAAK,0BAA0B,UAAU;AAC5C,WAAK,KAAK,IAAI,wBAAwB;AACtC,UAAI,KAAK;AAAqB,qBAAa,KAAK,mBAAmB;AACnE,iBAAW,UAAU,KAAK;AAAS,eAAO,uBAAuB;AAAA,IAClE,OAAO;AACN,WAAK,KAAK,IAAI,yBAAyB,KAAK,uBAAuB;AACnE,UAAI,KAAK;AAAqB,aAAK,kBAAkB;AAAA,IACtD;AAEA,WAAO;AAAA,EACR;AAAA,EACA,kBAAkB,QAA8B;AAC/C,QAAI,CAAC,KAAK,qBAAqB;AAC9B,UAAI;AAAQ,eAAO,UAAU,8BAA8B;AAC3D,aAAO;AAAA,IACR;AACA,QAAI,KAAK;AAAqB,mBAAa,KAAK,mBAAmB;AAEnE,UAAM,MAAM,KAAK,IAAI;AACrB,eAAW,UAAU,KAAK,SAAS;AAClC,YAAM,OAAO,OAAO;AACpB,UAAI,mBAAmB;AACvB,UAAI,OAAO,iBAAiB;AAAM,2BAAmB;AACrD,YAAM,mBAAmB,OAAO;AAEhC,UAAI,CAAC,oBAAoB,CAAC,kBAAkB;AAC3C,eAAO,uBAAuB;AAC9B;AAAA,MACD;AACA,UAAI,kBAAkB;AAAI;AAE1B,UAAI,MAAM,OAAO,KAAK,yBAAyB,OAAO,sBAAsB;AAC3E,YAAI;AACJ,YAAI,kBAAkB,MAAM;AAC3B,mBAAS;AAAA,QACV,OAAO;AACN,mBAAS;AAAA,QACV;AACA,aAAK,eAAe,OAAO,IAAI,QAAQ,MAAM;AAC7C,aAAK,KAAK,OAAO;AAAA,MAClB,WAAW,MAAM,OAAO,KAAK,wBAAwB,iCAAiC;AACrF,YAAI,OAAO;AAAsB;AACjC,YAAI,gBAAgB,KAAK,wBAAwB,MAAM;AACvD,YAAI,iBAAiB,GAAG;AACvB,0BAAgB;AAChB,iBAAO,iBAAiB,MAAM,KAAK,wBAAwB;AAAA,QAC5D;AAEA,eAAO,uBAAuB;AAC9B,eAAO,SAAS,6BAA6B,eAAe;AAAA,MAC7D,OAAO;AACN,eAAO,uBAAuB;AAAA,MAC/B;AAAA,IACD;AACA,QAAI,CAAC,KAAK;AAAO,WAAK,sBAAsB,WAAW,MAAM,KAAK,kBAAkB,GAAG,KAAK,qBAAqB;AAEjH,QAAI;AAAQ,aAAO,UAAU,oEAAoE;AAAA,EAClG;AAAA,EAEA,YAAY,SAAkB;AAC7B,SAAK,gBAAgB;AACrB,SAAK,eAAe,CAAC;AACrB,SAAK,KAAK,IAAI,wBAAwB,KAAK,gBAAgB,UAAU,YAAY;AAAA,EAClF;AAAA,EACA,WAAW,SAAkB;AAC5B,SAAK,eAAe;AACpB,SAAK,KAAK,IAAI,qBAAqB,UAAU,YAAY,wBAAwB,UAAU,KAAK,0CAA0C;AAAA,EAC3I;AAAA,EACA,qBAAqB,QAAiB;AACrC,SAAK,oBAAoB;AACzB,SAAK,KAAK,IAAI,0BAA0B,SAAS,QAAQ,8CAA8C;AAAA,EACxG;AAAA,EACA,cAAc,OAAgB;AAC7B,SAAK,aAAa;AAClB,SAAK,KAAK,IAAI,qBAAqB,QAAQ,OAAO,2BAA2B;AAAA,EAC9E;AAAA,EACA,eAAe,OAAgB;AAC9B,SAAK,cAAc;AACnB,SAAK,KAAK,IAAI,qCAAqC,QAAQ,OAAO,OAAO;AAAA,EAC1E;AAAA,EACA,kBAAkB,WAAoB;AACrC,SAAK,eAAe;AACpB,SAAK,KAAK,IAAI,kCAAkC,KAAK,gCAAgC;AAAA,EACtF;AAAA,EAEA,MAAM,UAAU,MAAY,cAAkB,QAA6B;AAC1E,QAAI,CAAC,KAAK,qBAAqB;AAC9B,aAAO,UAAU,8BAA8B;AAC/C;AAAA,IACD;AAEA,QAAI,EAAE,KAAK,MAAM,KAAK,cAAc;AACnC,aAAO,UAAU,gCAAgC;AACjD;AAAA,IACD;AAEA,QAAI,EAAE,gBAAgB,KAAK,cAAc;AACxC,aAAO,UAAU,gCAAgC;AACjD;AAAA,IACD;AAEA,UAAM,OAAO,KAAK,YAAY,KAAK,EAAE;AACrC,UAAM,KAAK,KAAK,YAAY,YAAY;AACxC,UAAM,mBAAmB,KAAK;AAC9B,QAAI,CAAC,kBAAkB,IAAI,EAAE,GAAG;AAC/B,aAAO,UAAU,gCAAgC;AACjD;AAAA,IACD;AAEA,QAAI,KAAK,UAAU,GAAG,QAAQ;AAC7B,WAAK,KAAK,IAAI,2EAA2E;AACzF;AAAA,IACD;AAEA,SAAK,SAAS;AACd,OAAG,SAAS;AAEZ,SAAK,gCAAgC;AACrC,SAAK,OAAO;AAEZ,UAAM,QAAQ,MAAM,QAAQ,KAAK,UAAU,EAAE,WAAW,OAAO,YAAY,MAAM;AACjF,QAAI,CAAC,OAAO;AACX,WAAK,SAAS;AACd,SAAG,SAAS;AAEZ,WAAK,gCAAgC;AACrC,WAAK,OAAO;AACZ;AAAA,IACD;AAEA,OAAG,iBAAiB,KAAK,IAAI;AAC7B,SAAK,mBAAmB;AAAA,MACvB;AAAA,MAAI,MAAM,MAAM,SAAS;AAAA,MAAM,QAAQ,MAAM,SAAS;AAAA,MAAQ,YAAY,MAAM,SAAS;AAAA,IAC1F;AACA,OAAG,mBAAmB;AAAA,MACrB;AAAA,MAAM,MAAM,MAAM,SAAS;AAAA,MAAM,QAAQ,MAAM,SAAS;AAAA,MAAQ,YAAY,MAAM,SAAS;AAAA,IAC5F;AACA,SAAK,SAAS,sBAAsB,KAAK,UAAU,EAAE,aAAa,GAAG,KAAK,CAAC,GAAG;AAC9E,OAAG,SAAS,sBAAsB,KAAK,UAAU,EAAE,YAAY,KAAK,KAAK,CAAC,GAAG;AAE7E,SAAK,uBAAuB;AAC5B,SAAK,OAAO;AAAA,EACb;AAAA,EACA,gBAAgB,MAAY,QAA6B;AACxD,QAAI,CAAC,KAAK,qBAAqB;AAC9B,UAAI;AAAQ,eAAO,UAAU,8BAA8B;AAC3D;AAAA,IACD;AAEA,QAAI,EAAE,KAAK,MAAM,KAAK,cAAc;AACnC,UAAI;AAAQ,eAAO,UAAU,gCAAgC;AAC7D;AAAA,IACD;AAEA,UAAM,SAAS,KAAK,YAAY,KAAK,EAAE;AACvC,UAAM,YAAY,OAAO;AACzB,QAAI,CAAC,WAAW;AAAI;AAEpB,WAAO,SAAS;AAChB,cAAU,GAAG,SAAS;AACtB,WAAO,mBAAmB;AAC1B,cAAU,GAAG,mBAAmB;AAChC,SAAK,OAAO,KAAK,MAAM,yCAAyC;AAChE,cAAU,GAAG,SAAS,wCAAwC;AAE9D,SAAK,uBAAuB;AAC5B,SAAK,gCAAgC;AACrC,SAAK,OAAO;AAAA,EACb;AAAA,EACA,MAAM,gBAAgB,MAAY,QAA6B;AAC9D,QAAI,CAAC,KAAK,qBAAqB;AAC9B,aAAO,UAAU,8BAA8B;AAC/C;AAAA,IACD;AAEA,QAAI,EAAE,KAAK,MAAM,KAAK,cAAc;AACnC,aAAO,UAAU,gCAAgC;AACjD;AAAA,IACD;AAEA,UAAM,SAAS,KAAK,YAAY,KAAK,EAAE;AACvC,UAAM,YAAY,OAAO;AACzB,QAAI,CAAC,WAAW;AAAM;AAEtB,UAAM,QAAQ,MAAM,QAAQ,KAAK,UAAU,EAAE,WAAW,OAAO,YAAY,MAAM;AACjF,QAAI,CAAC;AAAO;AAGZ,UAAM,OAAO,MAAM,IAAI,UAAU,KAAK,EAAE;AACxC,QAAI,CAAC,MAAM,aAAa,CAAC,KAAK;AAAW;AAGzC,QAAI,CAAC,UAAU,KAAK;AAAkB;AACtC,QAAI,CAAC,OAAO;AAAkB;AAE9B,UAAM,OAAO,MAAM,aAAa;AAAA,MAC/B,QAAQ,KAAK;AAAA,MACb,WAAW,KAAK,KAAK,SAAS;AAAA,MAC9B,SAAS,CAAC;AAAA,QACT,MAAM;AAAA,QACN,MAAM,UAAU;AAAA,QAChB,QAAQ,UAAU;AAAA,QAClB,YAAY,UAAU;AAAA,MACvB,GAAG;AAAA,QACF;AAAA,QACA,MAAM,MAAM,SAAS;AAAA,QACrB,QAAQ,MAAM,SAAS;AAAA,QACvB,YAAY,MAAM,SAAS;AAAA,MAC5B,CAAC;AAAA,MACD,OAAO,CAAC,QAAQ,YAAY,KAAK;AAAA,MACjC,eAAe,MAAM;AAAA,MACrB,MAAM;AAAA,MACN,UAAU,KAAK;AAAA,IAChB,CAAC;AAED,cAAU,KAAK,mBAAmB;AAClC,WAAO,mBAAmB;AAC1B,SAAK,OAAO,KAAK,MAAM,yCAAyC;AAChE,SAAK,OAAO,KAAK,MAAM,wCAAwC;AAG/D,QAAI,CAAC;AAAM;AAEX,cAAU,KAAK,kBAAkB,EAAE,IAAI,QAAQ,KAAK;AACpD,SAAK,KAAK,IAAI,2BAA2B,KAAK,QAAQ,KAAK,QAAQ,KAAK,QAAQ,EAAE,OAAO;AAEzF,SAAK,uBAAuB;AAC5B,QAAI,KAAK,0BAA0B;AAAU,WAAK,kBAAkB;AACpE,QAAI,KAAK;AAAY,WAAK,KAAK,WAAW;AAC1C,SAAK,OAAO;AAAA,EACb;AAAA,EAEA,uBAAuB;AACtB,WAAO,IAAI,QAAQ,IAAI,KAAK,UAAU,EAAE,OAAO;AAAA,EAChD;AAAA,EACA,QAAQ,MAAY;AACnB,WAAO,KAAK,eAAe,KAAK,IAAI,MAAM,2BAA2B,IAAI;AAAA,EAC1E;AAAA,EACA,UAAU,MAAY,YAAwB;AAC7C,SAAK,UAAU,MAAM,UAAU;AAAA,EAChC;AAAA,EACA,mBAAmB,MAAY,YAAwB;AACtD,SAAK,UAAU,MAAM,UAAU;AAAA,EAChC;AAAA,EACA,SAAS,MAAY,WAAe;AACnC,QAAI,aAAa,KAAK,aAAa;AAClC,WAAK,aAAa,MAAM,SAAS;AAAA,IAClC;AAEA,SAAK,UAAU,IAAI;AAAA,EACpB;AAAA,EACA,aAAa,MAAgB,MAAY;AACxC,QAAI,CAAC,KAAK,MAAM,CAAC,KAAK;AAAI;AAC1B,QAAI,KAAK,iBAAiB,KAAK,SAAS,KAAK,aAAa,KAAK,GAAG,YAAY,KAAK,aAAa,KAAK,GAAG,UAAU;AACjH;AAAA,IACD;AACA,QAAI,KAAK,IAAI,UAAU;AAAG;AAC1B,eAAW,eAAe,KAAK,oBAAoB,GAAG;AACrD,YAAM,YAAY,MAAM,IAAI,YAAY,EAAE;AAC1C,UAAI,aAAa,UAAU,aAAa,KAAK,UAAU;AACtD,eAAO;AAAA,MACR;AAAA,IACD;AAAA,EACD;AAAA,EACA,YAAY,MAAgB,UAAc;AACzC,QAAI,KAAK,iBAAiB,IAAI,KAAK,MAAM;AAAG;AAC5C,SAAK,iBAAiB,IAAI,KAAK,MAAM;AACrC,SAAK,UAAU,IAAI;AACnB,QAAI,CAAC,KAAK;AAAM,YAAM,IAAI,MAAM,qCAAqC;AACrE,QAAI,CAAC,KAAK,MAAM,CAAC,KAAK;AAAI,YAAM,IAAI,MAAM,yCAAyC;AACnF,UAAM,KAAK,KAAK,YAAY,KAAK,GAAG,EAAE;AACtC,UAAM,KAAK,KAAK,YAAY,KAAK,GAAG,EAAE;AACtC,UAAM,SAAS,KAAK,YAAY,QAAQ;AACxC,UAAM,QAAS,KAAK,KAAiC,SAAS,CAAC,GAAG,CAAC;AAEnE,QAAI,SAAkC;AACtC,QAAI,OAAO,QAAQ;AAClB,SAAG,SAAS;AACZ,SAAG,QAAQ;AACX,SAAG,UAAU;AACb,eAAS;AAAA,IACV,WAAW,OAAO,QAAQ;AACzB,SAAG,SAAS;AACZ,SAAG,QAAQ;AACX,SAAG,UAAU;AACb,eAAS;AAAA,IACV;AAEA,OAAG,SAAS;AACZ,OAAG,SAAS;AACZ,OAAG,kBAAkB;AAErB,SAAK,uBAAuB;AAC5B,SAAK,gCAAgC;AAErC,QAAI,WAAW,UAAU,CAAC,KAAK,UAAU,oBAAoB;AAC5D,WAAK,KAAK,IAAI,yBAAyB,GAAG,QAAQ,GAAG,QAAQ,UAAU,MAAM,KAAK,GAAG,UAAU,KAAK,QAAQ;AAE5G,UAAI,KAAK,0BAA0B;AAAU,aAAK,kBAAkB;AACpE,WAAK,OAAO;AACZ,aAAO,KAAK,KAAK,OAAO;AAAA,IACzB;AACA,QAAI,WAAW,QAAQ;AACtB,SAAG,SAAS;AACZ,SAAG,SAAS;AAAA,IACb;AACA,OAAG,SAAS;AACZ,OAAG,SAAS;AACZ,QAAI,EAAE,GAAG,kBAAkB,GAAG,iBAAiB;AAE9C,YAAM,QAAQ,KAAK,UAAU,eAAe,CAAC,IAAI,EAAE,GAAG,QAA0B,KAAK;AACrF,UAAI,OAAO;AAEV,eAAO,KAAK,KAAK,IAAI,cAAc,8BAA8B,KAAK,GAAG,OAAO,KAAK,GAAG,QAAQ,WAAW,yBAAyB,KAAK,WAAW,4CAA4C,EAAE,OAAO;AAAA,MAC1M;AAAA,IACD;AACA,SAAK,KAAK,IAAI,yBAAyB,GAAG,QAAQ,GAAG,QAAQ,UAAU,MAAM,KAAK,GAAG,aAAa,KAAK,QAAQ;AAE/G,QAAI,KAAK,UAAU,kBAAkB,GAAG;AACvC,UAAI,CAAC,KAAK,KAAK,SAAS,aAAa,KAAK,UAAU,KAAK,SAAS,aAAa,KAAK,CAAC,OAAO,iBAAiB;AAC5G,cAAM,WAAW,MAAM,IAAI,QAAQ;AACnC,YAAI,UAAU,YAAY,CAAC,GAAG;AAC7B,eAAK,KAAK,MAAM,eAAe,MAAM,UAAU,SAAS,YAAY,CAAC,CAAC;AAAA,QACvE;AAAA,MACD;AACA,WAAK,gBAAgB;AAAA,IACtB,OAAO;AACN,UAAI,KAAK,0BAA0B;AAAU,aAAK,kBAAkB;AACpE,WAAK,OAAO;AAAA,IACb;AACA,SAAK,KAAK,OAAO;AAAA,EAClB;AAAA,EACA,kBAAkB;AACjB,UAAM,SAAS;AAAA,MACd,SAAU,KAAK,UAAU,WAAW,EAA2B,IAAI,YAAY;AAAA,MAC/E,QAAQ,KAAK;AAAA,MACb,WAAW,KAAK,UAAU;AAAA,MAC1B,aAAa,KAAK,eAAe;AAAA,IAClC;AACA,SAAK,KAAK,IAAI,mBAAmB,KAAK,UAAU,MAAM,GAAG;AACzD,UAAM,WAAW,KAAK,KAAK,SAAS;AACpC,QAAI,UAAU,mBAAmB;AAChC,UAAI,CAAC,SAAS;AAAa,iBAAS,cAAc,CAAC;AACnD,YAAM,OAAO,IAAI,QAAQ,IAAI,KAAK,IAAI,EAAE,SAAS,IAAI,QAAQ,IAAI,KAAK,IAAI,EAAE,OAC3E,GAAG,KAAK,SAAS,IAAI,QAAQ,IAAI,KAAK,UAAU,EAAE;AACnD,eAAS,YAAY,QAAQ,EAAE,MAAM,YAAY,KAAK,YAAY,MAAM,KAAK,IAAI,EAAE,CAAC;AAGpF,aAAO,SAAS,YAAY,SAAS,SAAS,mBAAmB;AAChE,iBAAS,YAAY,IAAI;AAAA,MAC1B;AACA,WAAK,KAAK,aAAa;AAAA,IACxB;AACA,SAAK,OAAO;AAAA,EACb;AACD;AAEA,SAAS,aAAa,WAA+B;AACpD,cAAY,KAAK,SAAS;AAC1B,UAAQ,WAAW;AAAA,IACnB,KAAK;AAAQ,kBAAY;AAAe;AAAA,IACxC,KAAK;AAAM,kBAAY;AAAc;AAAA,EACrC;AACA,SAAO,qBAAqB,SAAyC;AACtE;AAEA,SAAS,0BACR,eAAmC,UAA8B,QAChE;AACD,QAAM,gBAAgB,aAAa,aAAa;AAChD,MAAI,CAAC,eAAe;AACnB,WAAO,WAAW,GAAG,oCAAoC;AACzD,UAAM,iBAAiB,OAAO,KAAK,oBAAoB,EAAE,KAAK,IAAI;AAClE,WAAO,WAAW,gBAAgB,gBAAgB;AAClD;AAAA,EACD;AACA,SAAO,IAAI,cAAc,YAAY,EAAE;AACxC;AACA,SAAS,iBACR,MAAY,UAA8B,WAA+B,WACzE,SAAkB,cAAkC,MAA0B,QAC7E;AACD,MAAI,KAAK,SAAS,QAAQ;AACzB,WAAO,WAAW,gDAAgD;AAClE;AAAA,EACD;AACA,MAAI,KAAK,MAAM;AACd,WAAO,WAAW,yEAAyE,KAAK,KAAK,OAAO;AAC5G;AAAA,EACD;AACA,MAAI,MAAM,OAAO,UAAU;AAC1B,WAAO,WAAW,mEAAmE;AACrF;AAAA,EACD;AACA,QAAM,SAAS,IAAI,QAAQ,IAAI,QAAQ;AACvC,MAAI,OAAO,eAAe,YAAY,CAAC,OAAO,gBAAgB;AAC7D,WAAO,WAAW,GAAG,OAAO,sCAAsC;AAClE,SAAK,OAAO,MAAM,eAAe;AACjC;AAAA,EACD;AACA,QAAM,WAAW,KAAK,SAAS;AAC/B,MAAI,UAAU,gBAAgB,SAAS,eAAe,SAAS,mBAAmB;AACjF,UAAM,cAAc,SAAS,YAAY,IAAI,OAAK,EAAE,UAAU;AAC9D,QAAI,YAAY,SAAS,OAAO,EAAE,GAAG;AACpC,aAAO,WAAW,KAAK,OAAO,wCAAwC;AACtE;AAAA,IACD;AAAA,EACD;AACA,MAAI,CAAC,aAAa,SAAS,GAAG;AAC7B,WAAO,WAAW,GAAG,gCAAgC;AACrD,UAAM,aAAa,OAAO,KAAK,oBAAoB,EAAE,KAAK,IAAI;AAC9D,WAAO,WAAW,gBAAgB,YAAY;AAC9C;AAAA,EACD;AACA,MAAI,aAAa,SAAS,SAAS,IAAI,GAAG;AACzC,WAAO,WAAW,mDAAmD;AACrE;AAAA,EACD;AACA,MAAI,MAAM,KAAK,EAAE,QAAQ;AACxB,QAAI,OAAO,UAAU,IAAI,MAAM,MAAM;AACpC,YAAM,IAAI,KAAK,aAAa,8CAA8C;AAAA,IAC3E;AAEA,QAAI,KAAK,SAAS,wBAAwB;AACzC,YAAM,IAAI,KAAK,aAAa,uCAAuC,oCAAoC;AAAA,IACxG;AACA,QAAI,KAAK,SAAS,GAAG;AAAG,YAAM,IAAI,KAAK,aAAa,oDAAoD;AAAA,EACzG;AACA,QAAM,OAAO,KAAK,OAAO,IAAI;AAAA,IAC5B;AAAA,IAAM;AAAA,IAAQ,0BAA0B,WAAW,cAAc,MAAM;AAAA,IAAI;AAAA,IAAW;AAAA,IAAS;AAAA,EAChG;AACA,MAAI,UAAU;AACb,QAAI,OAAO,SAAS,cAAc;AAAU,WAAK,oBAAoB,SAAS,WAAW,MAAM;AAC/F,QAAI,SAAS,WAAW;AACvB,WAAK,YAAY,SAAS;AAC1B,UAAI,SAAS,cAAc;AAAM,aAAK,kBAAkB,IAAI;AAAA,IAC7D;AACA,QAAI,SAAS;AAAQ,WAAK,yBAAyB,SAAS,QAAQ,MAAM;AAC1E,QAAI,SAAS;AAAa,WAAK,eAAe,IAAI;AAClD,QAAI,SAAS;AAAY,WAAK,cAAc,IAAI;AAChD,QAAI,SAAS,iBAAiB;AAAO,WAAK,WAAW,KAAK;AAC1D,QAAI,SAAS,kBAAkB;AAAO,WAAK,YAAY,KAAK;AAAA,EAC7D;AACA,SAAO;AACR;AAEA,MAAM,WAA8B;AAAA,EACnC,WAAW;AAAA,EACX,YAAY,QAAQ,MAAM,MAAM;AAC/B,SAAK,aAAa;AAClB,WAAO,KAAK,YAAY;AACxB,QAAI,CAAC,KAAK,SAAS,aAAa,mBAAmB;AAClD,YAAM,IAAI,KAAK,aAAa,oDAAoD;AAAA,IACjF;AACA,QAAI,CAAC,KAAK,SAAS,aAAa,aAAa,QAAQ;AACpD,YAAM,IAAI,KAAK,aAAa,sEAAsE;AAAA,IACnG;AAEA,UAAM,QAAQ,KAAK,SAAS,YAAY;AACxC,UAAM,EAAE,MAAM,KAAK,IAAI,MAAM,CAAC;AAC9B,QAAI,MAAM,6BAA6B,KAAK,iBAAiB,KAAK,IAAI,IAAI,IAAI,WAAW;AACzF,QAAI,MAAM,SAAS,GAAG;AACrB,aAAO;AACP,aAAO,MAAM,OAAO,CAAC,GAAG,MAAM,MAAM,CAAC,EAAE,IAAI,OAAK,EAAE,IAAI,EAAE,KAAK,IAAI;AAAA,IAClE;AACA,SAAK,aAAa,GAAG;AAAA,EACtB;AAAA,EACA,iBAAiB,CAAC,mIAAmI;AAAA,EAErJ,MAAM;AAAA,EACN,OAAO;AAAA,EACP,aAAa;AAAA,EACb,YAAY;AAAA,IACX,GAAG,QAAQ,MAAM,MAAM;AACtB,aAAO,KAAK,YAAY;AACxB,UAAI,CAAC,KAAK,aAAa;AAAG;AAC1B,YAAM,SAAS,CAAC;AAChB,iBAAW,YAAY,MAAM,MAAM,OAAO,GAAG;AAC5C,cAAM,aAAa,SAAS,QAAQ,UAAU;AAC9C,YAAI,CAAC;AAAY;AACjB,YAAI,SAAS,SAAS,aAAa,SAAS,SAAS,cAAc,SAAS,SAAS;AAAW;AAChG,eAAO,KAAK;AAAA,UACX,MAAM,SAAS;AAAA,UAAQ,OAAO,KAAK;AAAA,UAAO,QAAQ,WAAW;AAAA,UAC7D,WAAW,WAAW,UAAU;AAAA,UAAM,WAAW,WAAW;AAAA,QAC7D,CAAC;AAAA,MACF;AACA,WAAK,UAAU,qBAAqB,KAAK,UAAU,MAAM,GAAG;AAAA,IAC7D;AAAA,IACA,OAAO;AACN,aAAO,KAAK,MAAM,kBAAkB;AAAA,IACrC;AAAA,IACA,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,OAAO,QAAQ,MAAM,MAAM,YAAY,KAAK;AAC3C,YAAM,IAAI,KAAK,aAAa,GAAG,KAAK,WAAW,KAAK,8CAA8C,KAAK,sDAAsD;AAAA,IAC9J;AAAA,IACA,eAAe;AAAA,IACf,SAAS,QAAQ,MAAM,MAAM,YAAY,KAAK;AAC7C,aAAO,KAAK,YAAY;AACxB,WAAK,SAAS,kBAAkB,MAAM,IAAI;AAC1C,UAAI,CAAC,QAAQ;AACZ,YAAI,KAAK,SAAS,aAAa,eAAe;AAC7C,iBAAO,KAAK,UAAU,uCAAuC;AAAA,QAC9D,OAAO;AACN,iBAAO,KAAK,UAAU,wCAAwC;AAAA,QAC/D;AAAA,MACD;AAEA,YAAM,SAAS,OAAO,YAAY;AAClC,UAAI,KAAK,SAAS,MAAM,GAAG;AAC1B,YAAI,KAAK,SAAS,aAAa;AAAe,iBAAO,KAAK,WAAW,+CAA+C;AACpH,YAAI,CAAC,KAAK,SAAS;AAAa,eAAK,SAAS,cAAc,CAAC;AAC7D,aAAK,SAAS,YAAY,gBAAgB;AAC1C,aAAK,aAAa;AAClB,aAAK,iBAAiB,4CAA4C,KAAK,MAAM;AAC7E,aAAK,OAAO,sBAAsB,MAAM,IAAI;AAAA,MAC7C,WAAW,KAAK,QAAQ,MAAM,GAAG;AAChC,YAAI,CAAC,KAAK,SAAS,aAAa;AAAe,iBAAO,KAAK,WAAW,gDAAgD;AACtH,YAAI,CAAC,KAAK,SAAS;AAAa,eAAK,SAAS,cAAc,CAAC;AAC7D,aAAK,SAAS,YAAY,gBAAgB;AAC1C,aAAK,aAAa;AAClB,aAAK,iBAAiB,6CAA6C,KAAK,MAAM;AAC9E,aAAK,OAAO,sBAAsB,MAAM,KAAK;AAAA,MAC9C,OAAO;AACN,eAAO,KAAK,UAAU,gBAAgB,cAAc;AAAA,MACrD;AAEA,WAAK,aAAa;AAAA,IACnB;AAAA,IACA,KAAK;AAAA,IACL,OAAO,QAAQ,MAAM,MAAM,YAAY,KAAK;AAC3C,aAAO,KAAK,YAAY;AACxB,WAAK,SAAS,eAAe,MAAM,IAAI;AACvC,YAAM,CAAC,QAAQ,WAAW,KAAK,KAAK,IAAI,IAAI,OAAO,MAAM,GAAG,EAAE,IAAI,UAAQ,KAAK,KAAK,CAAC;AACrF,UAAI,CAAC,UAAU,CAAC,UAAU,CAAC,WAAW;AACrC,eAAO,KAAK,UAAU,gBAAgB,sDAAsD;AAAA,MAC7F;AAEA,YAAM,OAA+B,iBAAiB,MAAM,QAAQ,WAAW,KAAK,OAAO,YAAY,KAAK,MAAM,IAAI;AACtH,UAAI,MAAM;AACT,aAAK,iBAAiB,GAAG,KAAK,gCAAgC,KAAK,oBAAoB;AACvF,aAAK,OAAO,eAAe,MAAM,KAAK,UAAU;AAChD,YAAI,KAAK,SAAS,aAAa,eAAe;AAC7C,gBAAM,WAAW,MAAM,OAAO,OAAO,YAAY,aAAa;AAC9D,cAAI,YAAY,aAAa,MAAM;AAClC,qBAAS;AAAA,cACR,iBAAM,sCAAsC,KAAK,2BACjD,iBAAM,eAAe,IAAI,QAAQ,IAAI,KAAK,IAAI,EAAE,wCAChD,YAAY,KAAK;AAAA,YAClB,EAAE,OAAO;AAAA,UACV;AAAA,QACD;AAAA,MACD;AAAA,IACD;AAAA,IACA,QAAQ,QAAQ,MAAM,MAAM;AAC3B,UAAI,CAAC,KAAK,aAAa;AAAG;AAC1B,UAAI,MAAM;AACV,UAAI,UAAU;AACd,iBAAW,UAAU,IAAI,QAAQ,IAAI,GAAG;AACvC,YAAI,CAAC,OAAO;AAAgB;AAC5B,cAAM,OAAO,OAAO,KAAK,WAAW,QAAQ,IAAI,OAAO,IAAI,OAAO,KAAK,MAAM,CAAC,IAAI,OAAO;AACzF,YAAI,OAAO,YAAY,SAAS;AAC/B,oBAAU,OAAO;AACjB,iBAAO,iBAAM,qBAAqB,iCAAiC;AAAA,QACpE,OAAO;AACN,iBAAO,iBAAM,oBAAoB;AAAA,QAClC;AAAA,MACD;AACA,WAAK,aAAa,iFAAiF,qBAAqB;AAAA,IACzH;AAAA,IACA,QAAQ,QAAQ,MAAM,MAAM;AAC3B,aAAO,KAAK,YAAY;AACxB,YAAM,CAAC,QAAQ,GAAG,YAAY,IAAI,OAAO,MAAM,GAAG,EAAE,IAAI,UAAQ,KAAK,KAAK,CAAC;AAC3E,UAAI,CAAC,QAAQ;AACZ,eAAO,KAAK,UAAU,uCAAuC;AAAA,MAC9D;AACA,YAAM,SAAS,aAAa,KAAK,GAAG;AACpC,YAAM,aAAa,MAAM,IAAI,MAAM;AACnC,WAAK,SAAS,kBAAkB,YAAY,IAAI;AAEhD,YAAM,eAAe,aAAa,WAAW,KAAK,KAAK,MAAM;AAC7D,UAAI,CAAC;AAAY,eAAO;AACxB,UAAI,QAAQ,SAAS,mBAAmB;AACvC,eAAO,KAAK,WAAW,4CAA4C,+BAA+B;AAAA,MACnG;AAEA,UAAI,WAAW,YAAY,MAAM,UAAU;AAAG,eAAO,KAAK,WAAW,+CAA+C;AAEpH,YAAM,aAAa;AAAA,QAClB,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,YAAY,KAAK,IAAI,IAAI;AAAA,QACzB;AAAA,MACD;AACA,UAAI,YAAY;AACf,oBAAY,WAAW,MAAM,YAAY,UAAU;AAAA,MACpD,OAAO;AACN,oBAAY,eAAe,MAAM,cAAc,UAAU;AAAA,MAC1D;AACA,WAAK,QAAQ,UAAU,GAAG,iBAAiB,YAAY;AAEvD,WAAK,OAAO,WAAW,YAAY,MAAM;AACzC,WAAK;AAAA,QACJ,GAAG,aAAa,WAAW,OAAO,uDAAuD,KAAK,UAAU;AAAA,MACzG;AAAA,IACD;AAAA,IACA,UAAU,QAAQ,MAAM,MAAM;AAC7B,aAAO,KAAK,YAAY;AACxB,eAAS,OAAO,KAAK;AACrB,UAAI,CAAC,QAAQ;AACZ,eAAO,KAAK,UAAU,+BAA+B;AAAA,MACtD;AACA,YAAM,aAAa,MAAM,IAAI,KAAK,MAAM,CAAC;AACzC,WAAK,SAAS,kBAAkB,YAAY,IAAI;AAEhD,YAAM,eAAe,KAAK,cAAc,KAAK,MAAM,CAAC;AAEpD,UAAI,CAAC,WAAW,YAAY,MAAM,YAAY;AAAG,eAAO,KAAK,WAAW,0CAA0C;AAElH,UAAI,YAAY;AACf,oBAAY,aAAa,MAAM,cAAc,WAAW,KAAK;AAAA,MAC9D;AACA,WAAK,iBAAiB,GAAG,aAAa,WAAW,OAAO,yDAAyD,KAAK,OAAO;AAC7H,WAAK,OAAO,cAAc,YAAY,MAAM,EAAE,MAAM,GAAG,QAAQ,EAAE,CAAC;AAAA,IACnE;AAAA,IACA,GAAG;AAAA,IACH,IAAI;AAAA,IACJ,KAAK,QAAQ,MAAM,MAAM;AACxB,aAAO,KAAK,YAAY;AACxB,YAAM,aAAa,KAAK,YAAY,UAAU;AAC9C,iBAAW,QAAQ,MAAM,IAAI;AAAA,IAC9B;AAAA,IACA,GAAG;AAAA,IACH,KAAK;AAAA,IACL,MAAM,QAAQ,MAAM,MAAM;AACzB,aAAO,KAAK,YAAY;AACxB,YAAM,aAAa,KAAK,YAAY,UAAU;AAC9C,UAAI,WAAW,qBAAqB;AACnC,YAAI,WAAW,oBAAoB,EAAE,KAAK,YAAU,OAAO,OAAO,KAAK,EAAE,GAAG;AAC3E,qBAAW,eAAe,KAAK,IAAI,MAAM,MAAM,IAAI;AAAA,QACpD,OAAO;AACN,eAAK,WAAW,wDAAwD;AAAA,QACzE;AAAA,MACD,OAAO;AACN,mBAAW,WAAW,KAAK,IAAI,IAAI;AAAA,MACpC;AAAA,IACD;AAAA,IACA,SAAS,QAAQ,MAAM;AACtB,UAAI,CAAC,KAAK,aAAa;AAAG;AAC1B,aAAO,KAAK,YAAY;AACxB,YAAM,aAAa,KAAK,YAAY,UAAU;AAC9C,YAAM,QAAQ,aAAa,WAAW,oBAAoB,EAAE,KAAK,CAAC;AAClE,WAAK;AAAA,QACJ,WAAW,MAAM,UAAU,WAAW,QAAQ,WAC9C,iBAAM,uDAAuD,MAAM,KAAK,IAAI;AAAA,MAC7E;AAAA,IACD;AAAA,IACA,UAAU,QAAQ,MAAM,MAAM;AAC7B,aAAO,KAAK,YAAY;AACxB,YAAM,aAAa,KAAK,YAAY,UAAU;AAC9C,iBAAW,UAAU,IAAI;AACzB,WAAK,UAAU,2CAA2C;AAAA,IAC3D;AAAA,IACA,UAAU,QAAQ,MAAM,MAAM,YAAY,KAAK;AAC9C,aAAO,KAAK,YAAY;AACxB,YAAM,aAAa,KAAK,YAAY,UAAU;AAC9C,UAAI,CAAC,QAAQ;AACZ,eAAO,KAAK,UAAU,gBAAgB,YAAY;AAAA,MACnD;AACA,WAAK,WAAW,UAAU,MAAM,KAAK,MAAM,GAAG,IAAI;AAAA,IACnD;AAAA,IACA,gBAAgB,QAAQ,MAAM,MAAM;AACnC,aAAO,KAAK,YAAY;AACxB,YAAM,aAAa,KAAK,YAAY,UAAU;AAC9C,iBAAW,gBAAgB,MAAM,IAAI;AAAA,IACtC;AAAA,IACA,gBAAgB,QAAQ,MAAM,MAAM;AACnC,aAAO,KAAK,YAAY;AACxB,YAAM,aAAa,KAAK,YAAY,UAAU;AAC9C,WAAK,WAAW,gBAAgB,MAAM,IAAI;AAAA,IAC3C;AAAA,IACA,MAAM,IAAI,QAAQ,MAAM,MAAM,YAAY;AACzC,aAAO,KAAK,YAAY;AACxB,YAAM,aAAa,KAAK,YAAY,UAAU;AAC9C,UAAI,QAAQ,gBAAgB,WAAW,IAAI,UAAU,GAAG;AACvD;AAAA,MACD;AACA,YAAM,SAAS,MAAM,mBAAmB,IAAI,WAAW,UAAU,EAAE,aAAa,KAAK,eAAe,IAAI;AACxG,UAAI,OAAO,WAAW,GAAG,GAAG;AAC3B,mBAAW,MAAM,yCAAyC;AAAA,MAC3D,OAAO;AACN,cAAM,aAAa,IAAI,QAAQ,IAAI,WAAW,UAAU,EAAE;AAE1D,cAAM,UAAU,OAAO,MAAM,CAAC,EAAE,MAAM,UAAU,EAAE,KAAK,iBAAiB;AACxE,mBAAW,MAAM;AAAA;AAAA,IAA0D,QAAQ,QAAQ,OAAO,MAAM,GAAG;AAAA,MAC5G;AAAA,IACD;AAAA,IACA,aAAa;AAAA,IACb,aAAa;AAAA,IACb,WAAW;AAAA,IACX,gBAAgB,QAAQ,MAAM;AAC7B,aAAO,KAAK,YAAY;AACxB,YAAM,aAAa,KAAK,YAAY,UAAU;AAC9C,UAAI,CAAC,KAAK,aAAa;AAAG;AAC1B,UAAI,WAAW,YAAY,SAAS,GAAG;AACtC,eAAO,KAAK,WAAW,gDAAgD;AAAA,MACxE;AACA,WAAK,UAAU,6EAA6E,WAAW,eAAe,SAAS;AAAA,IAChI;AAAA,IACA,QAAQ,QAAQ,MAAM,MAAM,YAAY,KAAK;AAC5C,aAAO,KAAK,YAAY;AACxB,WAAK,SAAS,eAAe,MAAM,IAAI;AACvC,YAAM,aAAa,KAAK,YAAY,UAAU;AAC9C,UAAI,CAAC,QAAQ;AACZ,eAAO,KAAK,UAAU,gBAAgB,4CAA4C;AAAA,MACnF;AACA,YAAM,CAAC,eAAe,KAAK,QAAQ,IAAI,OAAO,MAAM,GAAG,EAAE,IAAI,UAAQ,KAAK,KAAK,CAAC;AAChF,YAAM,YAAY,SAAS,GAAG;AAC9B,YAAM,YAAY,0BAA0B,eAAe,UAAU,IAAI;AACzE,UAAI,aAAa,WAAW,aAAa,WAAW,IAAI,GAAG;AAC1D,YAAI,aAAa,aAAa,GAAG;AAChC,qBAAW,YAAY;AACvB,cAAI,OAAO,wBAAwB,WAAW,YAAY,OAAO,sBAAsB;AACtF,oBAAQ,IAAI,sBAAsB,WAAW,KAAK,4CAA4C,WAAW,YAAY;AAAA,UACtH;AACA,eAAK,KAAK,qCAAqC,aAAa;AAAA,QAC7D,WAAW,WAAW,aAAa,CAAC,WAAW;AAC9C,qBAAW,YAAY;AACvB,eAAK,KAAK,qCAAqC,aAAa;AAAA,QAC7D;AACA,cAAM,UAAW,WAAW,YAAY,yBAAyB,WAAW,cAAc;AAC1F,aAAK,iBAAiB,GAAG,KAAK,+BAA+B,UAAU,OAAO,UAAU;AACxF,aAAK,OAAO,gBAAgB,MAAM,GAAG,UAAU,OAAO,SAAS;AAC/D,aAAK,UAAU,qBAAqB,UAAU,OAAO,UAAU;AAAA,MAChE;AAAA,IACD;AAAA,IACA,KAAK;AAAA,IACL,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,aAAa,QAAQ,MAAM,MAAM,YAAY,KAAK;AACjD,aAAO,KAAK,YAAY;AACxB,WAAK,SAAS,eAAe,MAAM,IAAI;AACvC,YAAM,aAAa,KAAK,YAAY,UAAU;AAC9C,eAAS,OAAO,KAAK;AACrB,UAAI,CAAC,QAAQ;AACZ,YAAI,WAAW,WAAW;AACzB,iBAAO,KAAK,UAAU,gBAAgB,wCAAwC,WAAW,WAAW;AAAA,QACrG,OAAO;AACN,iBAAO,KAAK,UAAU,gBAAgB,WAAW;AAAA,QAClD;AAAA,MACD;AACA,UAAI,WAAW,qBAAqB;AACnC,eAAO,KAAK,WAAW,mEAAmE;AAAA,MAC3F;AACA,YAAM,SAAS,OAAO,YAAY;AAClC,UAAI,CAAC,KAAK,YAAY,OAAO,SAAS,QAAQ,QAAQ,EAAE,SAAS,MAAM,GAAG;AACzE,YAAI,CAAC,WAAW;AAAW,iBAAO,KAAK,WAAW,4CAA4C;AAC9F,iBAAS;AAAA,MACV;AACA,YAAM,YAAY,SAAS,MAAM;AACjC,UAAI,cAAc,GAAG;AACpB,mBAAW,YAAY;AACvB,aAAK,iBAAiB,GAAG,KAAK,2CAA2C;AACzE,aAAK,OAAO,kBAAkB,MAAM,SAAS;AAC7C,aAAK,UAAU,yBAAyB;AAAA,MACzC,OAAO;AACN,YAAI,MAAM,SAAS,KAAK,YAAY,GAAG;AACtC,iBAAO,KAAK,WAAW,sDAAsD;AAAA,QAC9E;AACA,YAAI,cAAc,WAAW,WAAW;AACvC,iBAAO,KAAK,WAAW,0CAA0C,YAAY;AAAA,QAC9E;AACA,mBAAW,YAAY;AACvB,YAAI,OAAO,wBAAwB,WAAW,YAAY,OAAO,sBAAsB;AACtF,kBAAQ,IAAI,sBAAsB,WAAW,KAAK,4CAA4C,WAAW,YAAY;AAAA,QACtH;AACA,aAAK,iBAAiB,GAAG,KAAK,2CAA2C,WAAW,YAAY;AAChG,aAAK,OAAO,kBAAkB,MAAM,WAAW,UAAU,SAAS,CAAC;AACnE,aAAK,UAAU,yBAAyB,WAAW,YAAY;AAAA,MAChE;AACA,WAAK,KAAK,qCAAqC,WAAW,aAAa;AAAA,IACxE;AAAA,IACA,KAAK;AAAA,IACL,MAAM;AAAA,IACN,OAAO,QAAQ,MAAM,MAAM;AAC1B,aAAO,KAAK,YAAY;AACxB,WAAK,SAAS,eAAe,MAAM,IAAI;AACvC,YAAM,aAAa,KAAK,YAAY,UAAU;AAC9C,iBAAW,SAAS;AACpB,WAAK,iBAAiB,GAAG,KAAK,mCAAmC;AACjE,WAAK,OAAO,UAAU;AAAA,IACvB;AAAA,IACA,SAAS;AAAA,IACT,SAAS;AAAA,IACT,OAAO;AAAA,IACP,YAAY,QAAQ,MAAM,MAAM,YAAY,KAAK;AAChD,aAAO,KAAK,YAAY;AACxB,YAAM,aAAa,KAAK,YAAY,UAAU;AAC9C,UAAI,QAAQ,WAAW;AACtB,eAAO,KAAK,WAAW,qHAAqH;AAAA,MAC7I;AACA,UAAI,CAAC,QAAQ;AACZ,aAAK,UAAU,oCAAoC;AACnD,aAAK,UAAU,oGAAoG;AACnH,aAAK,MAAM,iBAAiB;AAC5B,YAAI,WAAW,YAAY,QAAQ;AAClC,iBAAO,KAAK,aAAa,kHAAkH,WAAW,8BAA8B;AAAA,QACrL;AACA;AAAA,MACD;AACA,WAAK,SAAS,eAAe,MAAM,IAAI;AACvC,UAAI,WAAW,qBAAqB;AACnC,eAAO,KAAK,WAAW,qEAAqE;AAAA,MAC7F;AACA,UAAI,WAAW,eAAe,MAAM,GAAG;AACtC,aAAK;AAAA,UACJ,uEAAuE,WAAW,eAAe;AAAA,QAClG;AACA,aAAK,iBAAiB,GAAG,KAAK,6CAA6C;AAC3E,aAAK,OAAO,cAAc,MAAM,WAAW,YAAY,KAAK,IAAI,CAAC;AACjE,aAAK,aAAa,kHAAkH,WAAW,8BAA8B;AAAA,MAC9K;AAAA,IACD;AAAA,IACA,cAAc;AAAA,IACd,cAAc;AAAA,IACd,YAAY;AAAA,IACZ,iBAAiB,QAAQ,MAAM,MAAM;AACpC,aAAO,KAAK,YAAY;AACxB,WAAK,SAAS,eAAe,MAAM,IAAI;AACvC,YAAM,aAAa,KAAK,YAAY,UAAU;AAC9C,UAAI,WAAW,qBAAqB;AACnC,eAAO,KAAK,WAAW,qEAAqE;AAAA,MAC7F;AACA,UAAI,WAAW,YAAY,SAAS,GAAG;AACtC,eAAO,KAAK,WAAW,gDAAgD;AAAA,MACxE;AACA,iBAAW,cAAc,CAAC;AAC1B,iBAAW,aAAa,WAAW;AACnC,UAAI,WAAW,SAAS,WAAW,qBAAqB,GAAG;AAC1D,mBAAW,OAAO,WAAW;AAC7B,aAAK,KAAK,sBAAsB,KAAK,UAAU,EAAE,QAAQ,WAAW,KAAK,CAAC,GAAG;AAC7E,mBAAW,OAAO;AAAA,MACnB;AACA,WAAK,OAAO,oDAAoD;AAChE,WAAK,iBAAiB,GAAG,KAAK,6CAA6C;AAC3E,WAAK,OAAO,iBAAiB;AAAA,IAC9B;AAAA,IACA,MAAM;AAAA,IACN,YAAY;AAAA,IACZ,QAAQ,QAAQ,MAAM,MAAM,YAAY,KAAK;AAC5C,aAAO,KAAK,YAAY;AACxB,WAAK,SAAS,eAAe,MAAM,IAAI;AACvC,YAAM,aAAa,KAAK,YAAY,UAAU;AAC9C,YAAM,OAAO,OAAO,KAAK;AACzB,UAAI,CAAC,MAAM;AACV,eAAO,KAAK,UAAU,gBAAgB,iCAAiC;AAAA,MACxE;AACA,WAAK,UAAU,IAAI;AACnB,UAAI,CAAC,QAAQ,OAAO,SAAS;AAAU;AAEvC,UAAI,KAAK,SAAS,wBAAwB;AACzC,eAAO,KAAK,WAAW,uCAAuC,oCAAoC;AAAA,MACnG;AACA,UAAI,KAAK,SAAS,GAAG;AAAG,eAAO,KAAK,WAAW,oDAAoD;AACnG,iBAAW,OAAO;AAClB,WAAK,KAAK,sBAAsB,KAAK,UAAU,EAAE,QAAQ,WAAW,KAAK,CAAC,GAAG;AAC7E,WAAK,iBAAiB,GAAG,KAAK,qCAAqC,WAAW,OAAO;AACrF,WAAK,OAAO,aAAa,MAAM,WAAW,IAAI;AAC9C,iBAAW,OAAO;AAAA,IACnB;AAAA,IACA,WAAW;AAAA,IACX,UAAU,QAAQ,MAAM,MAAM;AAC7B,aAAO,KAAK,YAAY;AACxB,WAAK,SAAS,eAAe,MAAM,IAAI;AACvC,YAAM,aAAa,KAAK,YAAY,UAAU;AAC9C,UAAI,WAAW,SAAS,WAAW;AAAY,eAAO,KAAK,WAAW,sCAAsC;AAC5G,iBAAW,OAAO,WAAW;AAC7B,WAAK,KAAK,sBAAsB,KAAK,UAAU,EAAE,QAAQ,WAAW,KAAK,CAAC,GAAG;AAC7E,WAAK,iBAAiB,GAAG,KAAK,qCAAqC;AACnE,WAAK,OAAO,gBAAgB;AAC5B,iBAAW,OAAO;AAAA,IACnB;AAAA,IACA,OAAO;AAAA,IACP,MAAM,QAAQ,MAAM,MAAM;AACzB,aAAO,KAAK,YAAY;AACxB,WAAK,SAAS,eAAe,MAAM,IAAI;AACvC,YAAM,aAAa,KAAK,YAAY,UAAU;AAC9C,UAAI,WAAW,gBAAgB,IAAI,GAAG;AACrC,aAAK,SAAS,IAAI,KAAK,+BAA+B;AAAA,MACvD;AAAA,IACD;AAAA,IACA,IAAI;AAAA,IACJ,WAAW,QAAQ,MAAM,MAAM,YAAY,KAAK;AAC/C,aAAO,KAAK,YAAY;AACxB,WAAK,SAAS,eAAe,MAAM,IAAI;AACvC,YAAM,aAAa,KAAK,YAAY,UAAU;AAC9C,UAAI,CAAC,QAAQ;AACZ,eAAO,KAAK,UAAU,gBAAgB,YAAY;AAAA,MACnD;AACA,YAAM,CAAC,QAAQ,MAAM,IAAI,OAAO,MAAM,GAAG,EAAE,IAAI,UAAQ,KAAK,KAAK,CAAC;AAClE,YAAM,aAAa,MAAM,IAAI,MAAM;AACnC,YAAM,eAAe,KAAK,cAAc,MAAM;AAC9C,UAAI,QAAQ,SAAS,mBAAmB;AACvC,eAAO,KAAK,WAAW,4CAA4C,+BAA+B;AAAA,MACnG;AACA,UAAI,WAAW,eAAe,cAAc,MAAM,MAAM,GAAG;AAC1D,aAAK,iBAAiB,GAAI,aAAa,WAAW,OAAO,wDAAyD,KAAK,OAAQ,SAAS,OAAO,SAAS,MAAM,IAAK;AACnK,aAAK,OAAO,WAAW,cAAc,MAAM;AAAA,MAC5C;AAAA,IACD;AAAA,IACA,KAAK;AAAA,IACL,QAAQ,QAAQ,MAAM,MAAM;AAC3B,aAAO,KAAK,YAAY;AACxB,WAAK,SAAS,eAAe,MAAM,IAAI;AACvC,YAAM,aAAa,KAAK,YAAY,UAAU;AAC9C,YAAM,CAAC,SAAS,OAAO,IAAI,OAAO,MAAM,GAAG,EAAE,IAAI,UAAQ,MAAM,IAAI,KAAK,KAAK,CAAC,CAAC;AAC/E,UAAI,CAAC;AAAS,eAAO,KAAK,WAAW,QAAQ,oBAAoB;AACjE,UAAI,CAAC;AAAS,eAAO,KAAK,WAAW,QAAQ,oBAAoB;AAEjE,iBAAW,YAAY,SAAS,SAAS,IAAI;AAAA,IAC9C;AAAA,IACA,WAAW;AAAA,IACX,aAAa,QAAQ,MAAM,MAAM,YAAY,KAAK;AACjD,aAAO,KAAK,YAAY;AACxB,WAAK,SAAS,eAAe,MAAM,IAAI;AACvC,YAAM,aAAa,KAAK,YAAY,UAAU;AAC9C,eAAS,OAAO,KAAK;AACrB,UAAI,CAAC,QAAQ;AACZ,eAAO,KAAK,UAAU,gBAAgB,sBAAsB;AAAA,MAC7D;AACA,YAAM,SAAS,OAAO,YAAY;AAClC,UAAK,KAAK,SAAS,MAAM,KAAK,WAAW,OAAQ,WAAW,SAAS;AACpE,YAAI,WAAW,qBAAqB;AACnC,iBAAO,KAAK,WAAW,qCAAqC;AAAA,QAC7D,WAAW,CAAC,WAAW,WAAW;AACjC,iBAAO,KAAK,WAAW,gDAAgD;AAAA,QACxE,OAAO;AACN,cAAI,WAAW,cAAc;AAC5B,mBAAO,KAAK,WAAW,4EAA4E;AAAA,UACpG;AACA,qBAAW,kBAAkB,IAAI;AACjC,eAAK,iBAAiB,yEAAyE,KAAK,MAAM;AAC1G,eAAK,OAAO,kBAAkB,MAAM,2BAA2B;AAAA,QAChE;AAAA,MACD,OAAO;AACN,YAAI,WAAW,OAAO,WAAW,cAAc,KAAK,QAAQ,MAAM,KAAK,WAAW,UAAU,WAAW,UAAU;AAChH,cAAI,CAAC,WAAW,gBAAgB,WAAW,qBAAqB,UAAU;AACzE,mBAAO,KAAK,WAAW,sDAAsD;AAAA,UAC9E;AACA,mBAAS;AACT,qBAAW,eAAe;AAAA,QAC3B;AACA,cAAM,UAAU,OAAO,YAAY,MAAM,QAAQ,WAAW,OAAO,MAAM,IAAI,KAAK;AAClF,YAAI,WAAW,KAAM,YAAY,YAAY,UAAU,KAAK,sBAAuB;AAClF,iBAAO,KAAK,WAAW,wEAAwE;AAAA,QAChG;AACA,YAAI,WAAW,oBAAoB,SAAS,IAAI,GAAG;AAClD,eAAK,iBAAiB,8CAA8C,aAAa,KAAK,MAAM;AAC5F,eAAK,OAAO,kBAAkB,MAAM,YAAY,WAAW,QAAQ,MAAM;AAAA,QAC1E;AAAA,MACD;AAAA,IACD;AAAA,IACA,QAAQ;AAAA,IACR,UAAU,QAAQ,MAAM,MAAM,YAAY,KAAK;AAC9C,aAAO,KAAK,YAAY;AACxB,WAAK,SAAS,eAAe,MAAM,IAAI;AACvC,YAAM,aAAa,KAAK,YAAY,UAAU;AAC9C,eAAS,OAAO,KAAK;AACrB,UAAI,CAAC,QAAQ;AACZ,YAAI,WAAW,0BAA0B,UAAU;AAClD,iBAAO,KAAK,UAAU,gBAAgB,uEAAwE,WAAW,wBAAwB,MAAO,cAAe;AAAA,QACxK,OAAO;AACN,iBAAO,KAAK,UAAU,gBAAgB,mBAAmB;AAAA,QAC1D;AAAA,MACD;AACA,UAAI,OAAO,YAAY,MAAM,cAAc,WAAW;AAAK,iBAAS;AACpE,YAAM,UAAU,OAAO,YAAY,MAAM,QAAQ,WAAW,OAAO,MAAM,IAAI,KAAK;AAClF,UAAI,WAAW,KAAM,YAAY,YAAY,UAAU,KAAK,sBAAuB;AAClF,eAAO,KAAK,WAAW,wEAAwE;AAAA,MAChG;AACA,UAAI,YAAY,WAAW,uBAAuB;AACjD,eAAO,KAAK,WAAW,+DAA+D,mBAAmB;AAAA,MAC1G;AACA,UAAI,WAAW,yBAAyB,SAAS,IAAI,GAAG;AACvD,aAAK,iBAAiB,mDAAmD,aAAa,KAAK,MAAM;AACjG,aAAK,OAAO,eAAe,MAAM,YAAY,WAAW,QAAQ,MAAM;AAAA,MACvE;AAAA,IACD;AAAA,IACA,UAAU,QAAQ,MAAM,MAAM;AAC7B,aAAO,KAAK,YAAY;AACxB,WAAK,SAAS,eAAe,MAAM,IAAI;AACvC,YAAM,aAAa,KAAK,YAAY,UAAU;AAC9C,UAAI,WAAW,0BAA0B,UAAU;AAClD,eAAO,KAAK,WAAW,uDAAuD;AAAA,MAC/E;AACA,iBAAW,kBAAkB,IAAI;AACjC,WAAK,QAAQ,GAAG,KAAK,2BAA2B;AAAA,IACjD;AAAA,IACA,OAAO;AAAA,IACP,UAAU;AAAA,IACV,UAAU;AAAA,IACV,YAAY,QAAQ,MAAM,MAAM,YAAY,KAAK;AAChD,aAAO,KAAK,YAAY;AACxB,WAAK,SAAS,eAAe,MAAM,IAAI;AACvC,YAAM,aAAa,KAAK,YAAY,UAAU;AAC9C,eAAS,OAAO,KAAK;AACrB,UAAI,CAAC,QAAQ;AACZ,YAAI,WAAW,eAAe;AAC7B,iBAAO,KAAK,UAAU,wEAAwE;AAAA,QAC/F,OAAO;AACN,iBAAO,KAAK,UAAU,2EAA2E;AAAA,QAClG;AAAA,MACD;AAEA,YAAM,SAAS,OAAO,YAAY;AAClC,UAAI,KAAK,SAAS,MAAM,KAAK,WAAW,WAAW,WAAW,WAAW;AACxE,YAAI,WAAW;AAAe,iBAAO,KAAK,WAAW,yDAAyD;AAC9G,mBAAW,YAAY,IAAI;AAC3B,aAAK,iBAAiB,+CAA+C,KAAK,MAAM;AAChF,aAAK,OAAO,cAAc,MAAM,OAAO;AAAA,MACxC,WAAW,KAAK,QAAQ,MAAM,KAAK,WAAW,cAAc,WAAW,cAAc;AACpF,YAAI,CAAC,WAAW;AAAe,iBAAO,KAAK,WAAW,mDAAmD;AACzG,mBAAW,YAAY,KAAK;AAC5B,aAAK,iBAAiB,kDAAkD,KAAK,MAAM;AACnF,aAAK,OAAO,cAAc,MAAM,UAAU;AAAA,MAC3C,OAAO;AACN,eAAO,KAAK,UAAU,gBAAgB,qBAAqB;AAAA,MAC5D;AAAA,IACD;AAAA,IACA,SAAS;AAAA,IACT,WAAW,QAAQ,MAAM,MAAM,YAAY,KAAK;AAC/C,aAAO,KAAK,YAAY;AACxB,WAAK,SAAS,eAAe,MAAM,IAAI;AACvC,YAAM,aAAa,KAAK,YAAY,UAAU;AAC9C,eAAS,OAAO,KAAK;AACrB,UAAI,CAAC,QAAQ;AACZ,YAAI,WAAW,cAAc;AAC5B,iBAAO,KAAK,UAAU,0DAA0D;AAAA,QACjF,OAAO;AACN,iBAAO,KAAK,UAAU,kEAAkE;AAAA,QACzF;AAAA,MACD;AAEA,YAAM,SAAS,OAAO,YAAY;AAClC,UAAI,KAAK,SAAS,MAAM,KAAK,WAAW,WAAW;AAClD,YAAI,WAAW;AAAc,iBAAO,KAAK,WAAW,oDAAoD;AACxG,mBAAW,WAAW,IAAI;AAC1B,aAAK,iBAAiB,8CAA8C,KAAK,MAAM;AAC/E,aAAK,OAAO,gBAAgB,MAAM,MAAM;AAAA,MACzC,WAAW,KAAK,QAAQ,MAAM,KAAK,WAAW,cAAc;AAC3D,YAAI,CAAC,WAAW;AAAc,iBAAO,KAAK,WAAW,wDAAwD;AAC7G,mBAAW,WAAW,KAAK;AAC3B,aAAK,iBAAiB,iDAAiD,KAAK,MAAM;AAClF,aAAK,OAAO,gBAAgB,MAAM,MAAM;AAAA,MACzC,OAAO;AACN,eAAO,KAAK,UAAU,gBAAgB,sBAAsB;AAAA,MAC7D;AAAA,IACD;AAAA,IACA,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,mBAAmB;AAAA,IACnB,kBAAkB,QAAQ,MAAM,MAAM,YAAY,KAAK;AACtD,aAAO,KAAK,YAAY;AACxB,WAAK,SAAS,eAAe,MAAM,IAAI;AACvC,YAAM,aAAa,KAAK,YAAY,UAAU;AAC9C,eAAS,OAAO,KAAK;AACrB,UAAI,CAAC,QAAQ;AACZ,eAAO,KAAK;AAAA,UACX,mBAAmB,WAAW,oBAAoB,mBAAmB;AAAA,QACtE;AAAA,MACD;AACA,YAAM,QAAQ,KAAK,SAAS,MAAM,IAAI,OAAO,KAAK,QAAQ,MAAM,IAAI,QAAQ;AAC5E,eAAS,QAAQ,OAAO;AACxB,UAAI,UAAU,QAAQ,CAAC,KAAK,MAAM,GAAG;AACpC,eAAO,KAAK,MAAM,YAAY;AAAA,MAC/B;AACA,UAAI,WAAW,sBAAsB,OAAO;AAC3C,eAAO,KAAK,WAAW,qCAAqC,QAAQ,aAAa,kCAAkC;AAAA,MACpH;AACA,iBAAW,qBAAqB,KAAK;AACrC,WAAK,iBAAiB,GAAG,KAAK,+BAA+B,QAAQ,aAAa,kCAAkC;AACpH,WAAK,OAAO,0BAA0B,MAAM,MAAM;AAAA,IACnD;AAAA,IACA,YAAY,QAAQ,MAAM,MAAM,YAAY,KAAK;AAChD,aAAO,KAAK,YAAY;AACxB,WAAK,SAAS,eAAe,MAAM,IAAI;AACvC,YAAM,aAAa,KAAK,YAAY,UAAU;AAC9C,eAAS,OAAO,KAAK;AACrB,YAAM,SAAS,UAAU;AACzB,UAAI,KAAK,SAAS,MAAM,GAAG;AAC1B,YAAI,WAAW,aAAa;AAC3B,gBAAM,IAAI,KAAK,aAAa,qDAAqD;AAAA,QAClF;AACA,mBAAW,eAAe,IAAI;AAC9B,aAAK,iBAAiB,+CAA+C,KAAK,MAAM;AAChF,aAAK,OAAO,oBAAoB,MAAM,IAAI;AAAA,MAC3C,WAAW,KAAK,QAAQ,MAAM,KAAK,WAAW,QAAQ;AACrD,YAAI,CAAC,WAAW,aAAa;AAC5B,gBAAM,IAAI,KAAK,aAAa,iDAAiD;AAAA,QAC9E;AACA,mBAAW,eAAe,KAAK;AAC/B,aAAK,iBAAiB,gDAAgD,KAAK,MAAM;AACjF,aAAK,OAAO,oBAAoB,MAAM,KAAK;AAAA,MAC5C,OAAO;AACN,eAAO,KAAK,UAAU,gBAAgB,cAAc;AAAA,MACrD;AAAA,IACD;AAAA,IACA,WAAW,QAAQ,MAAM,MAAM,YAAY,KAAK;AAC/C,aAAO,KAAK,YAAY;AACxB,WAAK,SAAS,eAAe,MAAM,IAAI;AACvC,YAAM,aAAa,KAAK,YAAY,UAAU;AAC9C,eAAS,OAAO,KAAK;AACrB,YAAM,SAAS,SAAS,OAAO,YAAY,IAAI;AAC/C,UAAI,KAAK,SAAS,MAAM,GAAG;AAC1B,mBAAW,cAAc,IAAI;AAC7B,mBAAW,UAAU,WAAW,SAAS;AACxC,iBAAO,iBAAiB,KAAK,MAAM,WAAW;AAAA,QAC/C;AACA,aAAK,iBAAiB,iDAAiD,KAAK,MAAM;AAClF,aAAK,OAAO,mBAAmB,MAAM,IAAI;AAAA,MAC1C,WAAW,KAAK,QAAQ,MAAM,KAAK,WAAW,QAAQ;AACrD,mBAAW,cAAc,KAAK;AAC9B,aAAK,iBAAiB,kDAAkD,KAAK,MAAM;AACnF,aAAK,OAAO,mBAAmB,MAAM,KAAK;AAAA,MAC3C,OAAO;AACN,eAAO,KAAK,UAAU,gBAAgB,cAAc;AAAA,MACrD;AAAA,IACD;AAAA,IACA,UAAU;AAAA,MACT,QAAQ,QAAQ,MAAM,MAAM;AAt7D/B;AAu7DI,eAAO,KAAK,YAAY;AACxB,aAAK,SAAS,WAAW,MAAM,IAAI;AACnC,YAAI,CAAC,UAAW,CAAC,KAAK,SAAS,MAAM,KAAK,CAAC,KAAK,QAAQ,MAAM,GAAI;AACjE,iBAAO,KAAK,MAAM,qBAAqB;AAAA,QACxC;AACA,cAAM,OAAO,KAAK,QAAQ,UAAU;AACpC,mBAAK,UAAS,gBAAd,GAAc,cAAgB,CAAC;AAC/B,YAAI,KAAK,SAAS,MAAM,GAAG;AAC1B,cAAI,KAAK,SAAS,YAAY,cAAc;AAC3C,kBAAM,IAAI,KAAK,aAAa,kDAAkD;AAAA,UAC/E;AACA,cAAI,QAAQ,CAAC,KAAK;AAAc,iBAAK,MAAM,qBAAqB;AAChE,eAAK,SAAS,YAAY,eAAe;AACzC,eAAK,aAAa;AAClB,eAAK,iBAAiB,+CAA+C,KAAK,MAAM;AAChF,eAAK,OAAO,iBAAiB,MAAM,gBAAgB;AAAA,QACpD,OAAO;AACN,cAAI,CAAC,KAAK,SAAS,YAAY,cAAc;AAC5C,kBAAM,IAAI,KAAK,aAAa,mDAAmD;AAAA,UAChF;AACA,cAAI,MAAM;AAAc,iBAAK,MAAM,wBAAwB;AAC3D,eAAK,SAAS,YAAY,eAAe;AACzC,eAAK,aAAa;AAClB,eAAK,iBAAiB,gDAAgD,KAAK,MAAM;AACjF,eAAK,OAAO,iBAAiB,MAAM,mBAAmB;AAAA,QACvD;AAAA,MACD;AAAA,MACA,SAAS,QAAQ,MAAM,MAAM;AAl9DhC;AAm9DI,eAAO,KAAK,YAAY;AACxB,aAAK,SAAS,WAAW,MAAM,IAAI;AACnC,YAAI,CAAC,UAAW,CAAC,KAAK,SAAS,MAAM,KAAK,CAAC,KAAK,QAAQ,MAAM;AAAI,iBAAO,KAAK,MAAM,qBAAqB;AACzG,cAAM,OAAO,KAAK,QAAQ,UAAU;AACpC,mBAAK,UAAS,gBAAd,GAAc,cAAgB,CAAC;AAC/B,YAAI,KAAK,SAAS,MAAM,GAAG;AAC1B,cAAI,KAAK,SAAS,YAAY,eAAe;AAC5C,kBAAM,IAAI,KAAK,aAAa,mDAAmD;AAAA,UAChF;AACA,cAAI,QAAQ,CAAC,KAAK;AAAe,iBAAK,MAAM,sBAAsB;AAClE,eAAK,SAAS,YAAY,gBAAgB;AAC1C,eAAK,aAAa;AAClB,eAAK,iBAAiB,gDAAgD,KAAK,MAAM;AACjF,eAAK,OAAO,iBAAiB,MAAM,iBAAiB;AAAA,QACrD,OAAO;AACN,cAAI,CAAC,KAAK,SAAS,YAAY,eAAe;AAC7C,kBAAM,IAAI,KAAK,aAAa,oDAAoD;AAAA,UACjF;AACA,cAAI,MAAM;AAAe,iBAAK,MAAM,yBAAyB;AAC7D,eAAK,SAAS,YAAY,gBAAgB;AAC1C,eAAK,aAAa;AAClB,eAAK,iBAAiB,iDAAiD,KAAK,MAAM;AAClF,eAAK,OAAO,iBAAiB,MAAM,oBAAoB;AAAA,QACxD;AAAA,MACD;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,mBAAmB;AAAA,MACnB,kBAAkB,QAAQ,MAAM,MAAM;AA/+DzC;AAg/DI,eAAO,KAAK,YAAY;AACxB,aAAK,SAAS,WAAW,MAAM,IAAI;AACnC,cAAM,OAAO,KAAK,QAAQ,UAAU;AACpC,mBAAK,UAAS,gBAAd,GAAc,cAAgB,CAAC;AAC/B,cAAM,QAAQ,KAAK,SAAS,MAAM,IAAI,OAAO,KAAK,QAAQ,MAAM,IAAI,QAAQ;AAC5E,YAAI,CAAC,UAAU,UAAU;AAAM,iBAAO,KAAK,MAAM,qBAAqB;AACtE,YAAI,KAAK,SAAS,YAAY,sBAAsB,OAAO;AAC1D,iBAAO,KAAK,WAAW,sCAAsC,QAAQ,aAAa,iCAAiC;AAAA,QACpH;AACA,aAAK,SAAS,YAAY,oBAAoB;AAC9C,aAAK,aAAa;AAClB,iBAAS,QAAQ,OAAO;AACxB,aAAK,OAAO,iBAAiB,MAAM,uBAAuB,QAAQ;AAClE,YAAI;AAAM,eAAK,MAAM,2BAA2B,QAAQ;AACxD,aAAK,iBAAiB,GAAG,KAAK,+BAA+B,QAAQ,aAAa,kCAAkC;AAAA,MACrH;AAAA,MACA,YAAY,QAAQ,MAAM,MAAM;AAhgEnC;AAigEI,eAAO,KAAK,YAAY;AACxB,aAAK,SAAS,WAAW,MAAM,IAAI;AACnC,YAAI,CAAC,UAAW,CAAC,KAAK,QAAQ,MAAM,KAAK,CAAC,KAAK,SAAS,MAAM;AAAI,iBAAO,KAAK,MAAM,qBAAqB;AACzG,cAAM,OAAO,KAAK,QAAQ,UAAU;AACpC,mBAAK,UAAS,gBAAd,GAAc,cAAgB,CAAC;AAC/B,YAAI,KAAK,QAAQ,MAAM,GAAG;AACzB,cAAI,CAAC,KAAK,SAAS,YAAY,aAAa;AAC3C,kBAAM,IAAI,KAAK,aAAa,kEAAkE;AAAA,UAC/F;AACA,cAAI,MAAM;AAAa,iBAAK,MAAM,uBAAuB;AACzD,eAAK,SAAS,YAAY,cAAc;AACxC,eAAK,aAAa;AAClB,eAAK,iBAAiB,+DAA+D,KAAK,MAAM;AAChG,eAAK,OAAO,iBAAiB,MAAM,sBAAsB;AAAA,QAC1D,OAAO;AACN,cAAI,KAAK,SAAS,YAAY,aAAa;AAC1C,kBAAM,IAAI,KAAK,aAAa,iEAAiE;AAAA,UAC9F;AACA,cAAI,QAAQ,CAAC,KAAK;AAAa,iBAAK,MAAM,sBAAsB;AAChE,eAAK,SAAS,YAAY,cAAc;AACxC,eAAK,aAAa;AAClB,eAAK,iBAAiB,8DAA8D,KAAK,MAAM;AAC/F,eAAK,OAAO,iBAAiB,MAAM,qBAAqB;AAAA,QACzD;AAAA,MACD;AAAA,MACA,WAAW,QAAQ,MAAM,MAAM;AA1hElC;AA2hEI,eAAO,KAAK,YAAY;AACxB,aAAK,SAAS,WAAW,MAAM,IAAI;AACnC,YAAI,CAAC,UAAW,CAAC,KAAK,QAAQ,MAAM,KAAK,CAAC,KAAK,SAAS,MAAM;AAAI,iBAAO,KAAK,MAAM,qBAAqB;AACzG,cAAM,OAAO,KAAK,QAAQ,UAAU;AACpC,mBAAK,UAAS,gBAAd,GAAc,cAAgB,CAAC;AAC/B,YAAI,KAAK,QAAQ,MAAM,GAAG;AACzB,cAAI,CAAC,KAAK,SAAS,YAAY,YAAY;AAC1C,kBAAM,IAAI,KAAK,aAAa,wDAAwD;AAAA,UACrF;AACA,cAAI,MAAM;AAAY,iBAAK,MAAM,sBAAsB;AACvD,eAAK,SAAS,YAAY,aAAa;AACvC,eAAK,aAAa;AAClB,eAAK,iBAAiB,qDAAqD,KAAK,MAAM;AACtF,eAAK,OAAO,iBAAiB,MAAM,qBAAqB;AAAA,QACzD,OAAO;AACN,cAAI,KAAK,SAAS,YAAY,YAAY;AACzC,kBAAM,IAAI,KAAK,aAAa,uDAAuD;AAAA,UACpF;AACA,cAAI,QAAQ,CAAC,KAAK;AAAY,iBAAK,MAAM,qBAAqB;AAC9D,eAAK,SAAS,YAAY,aAAa;AACvC,eAAK,aAAa;AAClB,eAAK,iBAAiB,oDAAoD,KAAK,MAAM;AACrF,eAAK,OAAO,iBAAiB,MAAM,oBAAoB;AAAA,QACxD;AAAA,MACD;AAAA,MACA,UAAU,QAAQ,MAAM,MAAM;AApjEjC;AAqjEI,eAAO,KAAK,YAAY;AACxB,aAAK,SAAS,WAAW,MAAM,IAAI;AACnC,cAAM,MAAM,OAAO,MAAM;AACzB,YAAI,CAAC,UAAW,CAAC,KAAK,SAAS,MAAM,KAAK,CAAC,KAAK,QAAQ,MAAM,KAAK,MAAM,GAAG,GAAI;AAC/E,iBAAO,KAAK,MAAM,qBAAqB;AAAA,QACxC;AACA,cAAM,OAAO,KAAK,QAAQ,UAAU;AACpC,mBAAK,UAAS,gBAAd,GAAc,cAAgB,CAAC;AAC/B,YAAI,KAAK,QAAQ,MAAM,GAAG;AACzB,cAAI,CAAC,KAAK,SAAS,YAAY,WAAW;AACzC,kBAAM,IAAI,KAAK,aAAa,qDAAqD;AAAA,UAClF;AACA,cAAI,QAAQ,CAAC,KAAK,uBAAuB,KAAK,0BAA0B,UAAU;AACjF,iBAAK,MAAM,uBAAuB;AAAA,UACnC;AACA,eAAK,SAAS,YAAY,YAAY;AACtC,eAAK,aAAa;AAClB,eAAK,iBAAiB,kDAAkD,KAAK,MAAM;AACnF,eAAK,OAAO,iBAAiB,MAAM,oBAAoB;AAAA,QACxD,WAAW,KAAK,SAAS,MAAM,KAAK,WAAW,KAAK;AACnD,cAAI,KAAK,SAAS,YAAY,cAAc,MAAM;AACjD,kBAAM,IAAI,KAAK,aAAa,wDAAwD;AAAA,UACrF;AACA,eAAK,SAAS,YAAY,YAAY;AACtC,cAAI,QAAQ,CAAC,KAAK,uBAAuB,KAAK;AAAW,iBAAK,MAAM,uBAAuB;AAC3F,eAAK,aAAa;AAClB,eAAK,iBAAiB,qDAAqD,KAAK,MAAM;AACtF,eAAK,OAAO,iBAAiB,MAAM,eAAe;AAAA,QACnD,WAAW,CAAC,MAAM,GAAG,GAAG;AACvB,gBAAM,UAAU,MAAM,KAAK;AAC3B,cAAI,UAAU,MAAM,KAAK,OAAQ,UAAU,KAAK,sBAAsB;AACrE,kBAAM,IAAI,KAAK,aAAa,4CAA4C;AAAA,UACzE;AACA,cAAI,KAAK,SAAS,YAAY,cAAc,SAAS;AACpD,kBAAM,IAAI,KAAK,aAAa,oDAAoD,MAAM;AAAA,UACvF;AACA,eAAK,SAAS,YAAY,YAAY;AACtC,cAAI,QAAQ,CAAC,KAAK,uBAAuB,KAAK,qBAAqB,UAAU;AAC5E,iBAAK,MAAM,sBAAsB,KAAK;AAAA,UACvC;AACA,eAAK,aAAa;AAClB,eAAK,iBAAiB,wBAAwB,yCAAyC,KAAK,MAAM;AAClG,eAAK,OAAO,iBAAiB,MAAM,cAAc,eAAe;AAAA,QACjE;AAAA,MACD;AAAA,MACA,OAAO,QAAQ,MAAM,MAAM;AAlmE9B;AAmmEI,eAAO,KAAK,YAAY;AACxB,aAAK,SAAS,WAAW,MAAM,IAAI;AACnC,cAAM,MAAM,OAAO,MAAM;AACzB,YAAI,CAAC,UAAW,CAAC,KAAK,QAAQ,MAAM,KAAK,MAAM,GAAG;AAAI,iBAAO,KAAK,MAAM,qBAAqB;AAC7F,cAAM,OAAO,KAAK,QAAQ,UAAU;AACpC,mBAAK,UAAS,gBAAd,GAAc,cAAgB,CAAC;AAC/B,YAAI,KAAK,QAAQ,MAAM,GAAG;AACzB,cAAI,CAAC,KAAK,SAAS,YAAY,QAAQ;AACtC,kBAAM,IAAI,KAAK,aAAa,sEAAsE;AAAA,UACnG;AACA,cAAI,QAAQ,CAAC,KAAK,uBAAuB,KAAK,0BAA0B,UAAU;AACjF,iBAAK,MAAM,kBAAkB;AAAA,UAC9B;AACA,iBAAO,KAAK,SAAS,YAAY;AACjC,eAAK,aAAa;AAClB,eAAK,iBAAiB,mEAAmE,KAAK,MAAM;AACpG,eAAK,OAAO,iBAAiB,MAAM,iBAAiB;AAAA,QACrD,WAAW,CAAC,MAAM,GAAG,GAAG;AACvB,gBAAM,UAAU,MAAM,KAAK;AAC3B,cAAI,UAAU,MAAM,KAAK,OAAQ,UAAU,KAAK,sBAAsB;AACrE,kBAAM,IAAI,KAAK,aAAa,oDAAoD;AAAA,UACjF;AACA,cAAI,KAAK,SAAS,YAAY,WAAW,SAAS;AACjD,kBAAM,IAAI,KAAK,aAAa,qEAAqE,MAAM;AAAA,UACxG;AACA,eAAK,SAAS,YAAY,SAAS;AACnC,cAAI,MAAM,0BAA0B,UAAU;AAC7C,iBAAK,MAAM,gBAAgB,KAAK;AAAA,UACjC;AACA,eAAK,aAAa;AAClB,eAAK,iBAAiB,yCAAyC,yCAAyC,KAAK,MAAM;AACnH,eAAK,OAAO,iBAAiB,MAAM,WAAW,eAAe;AAAA,QAC9D;AAAA,MACD;AAAA,MACA,UAAU,QAAQ,MAAM,MAAM;AAroEjC;AAsoEI,eAAO,KAAK,YAAY;AACxB,aAAK,SAAS,WAAW,MAAM,IAAI;AACnC,cAAM,MAAM,SAAS,MAAM;AAC3B,YAAI,CAAC,UAAW,CAAC,KAAK,QAAQ,MAAM,KAAK,MAAM,GAAG;AAAI,iBAAO,KAAK,MAAM,qBAAqB;AAC7F,cAAM,OAAO,KAAK,QAAQ,UAAU;AACpC,mBAAK,UAAS,gBAAd,GAAc,cAAgB,CAAC;AAC/B,YAAI,KAAK,QAAQ,MAAM,GAAG;AACzB,cAAI,CAAC,KAAK,SAAS,YAAY,WAAW;AACzC,kBAAM,IAAI,KAAK,aAAa,qDAAqD;AAAA,UAClF;AACA,cAAI,QAAQ,CAAC,KAAK,uBAAuB,KAAK,WAAW;AACxD,iBAAK,MAAM,wBAAwB;AAAA,UACpC;AACA,iBAAO,KAAK,SAAS,YAAY;AACjC,eAAK,aAAa;AAClB,eAAK,iBAAiB,kDAAkD,KAAK,MAAM;AACnF,eAAK,OAAO,iBAAiB,MAAM,mBAAmB;AAAA,QACvD,WAAW,CAAC,MAAM,GAAG,GAAG;AACvB,cAAI,MAAM,GAAG;AACZ,kBAAM,IAAI,KAAK,aAAa,oCAAoC;AAAA,UACjE;AACA,cAAI,KAAK,SAAS,YAAY,cAAc,KAAK;AAChD,kBAAM,IAAI,KAAK,aAAa,qDAAqD,MAAM;AAAA,UACxF;AACA,eAAK,SAAS,YAAY,YAAY;AACtC,cAAI,QAAQ,CAAC,KAAK,uBAAuB,CAAC,KAAK,WAAW;AACzD,iBAAK,MAAM,sBAAsB,KAAK;AACtC,gBAAI,KAAK,SAAS,YAAY,cAAc;AAAM,mBAAK,MAAM,oBAAoB;AAAA,UAClF;AACA,eAAK,aAAa;AAClB,eAAK,iBAAiB,yBAAyB,+BAA+B,KAAK,MAAM;AACzF,eAAK,OAAO,iBAAiB,MAAM,cAAc,KAAK;AACtD,cAAI,OAAO,wBAAwB,KAAK,SAAS,YAAY,YAAY,OAAO,sBAAsB;AACrG,oBAAQ,IAAI,sBAAsB,KAAK,uDAAuD,KAAK,SAAS,YAAY,YAAY;AAAA,UACrI;AAAA,QACD,OAAO;AACN,iBAAO,KAAK,UAAU,UAAU,KAAK,WAAW,KAAK,sBAAsB;AAAA,QAC5E;AAAA,MACD;AAAA,MACA,YAAY,QAAQ,MAAM,MAAM;AA7qEnC;AA8qEI,eAAO,KAAK,YAAY;AACxB,aAAK,SAAS,WAAW,MAAM,IAAI;AACnC,YAAI,MAAM,SAAS,MAAM;AACzB,cAAM,cAAc,KAAK,MAAM,MAAM;AACrC,YAAI,KAAK,QAAQ,MAAM,KAAK;AAAa,gBAAM;AAC/C,YAAI,MAAM,GAAG,KAAK,MAAM,MAAM,MAAM,GAAG;AACtC,iBAAO,KAAK,MAAM,qBAAqB;AAAA,QACxC;AACA,mBAAK,UAAS,gBAAd,GAAc,cAAgB,CAAC;AAC/B,YAAI,OAAO,GAAG;AACb,cAAI,KAAK,SAAS,YAAY,sBAAsB,KAAK;AACxD,kBAAM,IAAI,KAAK,aAAa,4DAA4D,MAAM;AAAA,UAC/F;AACA,eAAK,SAAS,YAAY,oBAAoB;AAC9C,cAAI,KAAK,SAAS,YAAY,aAAa;AAC1C,mBAAO,KAAK,SAAS,YAAY,YAAY,SAAS,KAAK;AAC1D,mBAAK,SAAS,YAAY,YAAY,IAAI;AAAA,YAC3C;AAAA,UACD;AACA,eAAK,aAAa;AAClB,eAAK,iBAAiB,qDAAqD,UAAU,KAAK,OAAO;AACjG,eAAK,OAAO,iBAAiB,MAAM,iBAAiB,iBAAiB;AAAA,QACtE,OAAO;AACN,cAAI,eAAe,KAAK,SAAS,YAAY,aAAa;AACzD,mBAAO,KAAK,SAAS,YAAY;AACjC,iBAAK,iBAAiB,0CAA0C,KAAK,OAAO;AAC5E,iBAAK,OAAO,iBAAiB,MAAM,sBAAsB;AAAA,UAC1D;AACA,cAAI,CAAC,KAAK,SAAS,YAAY,mBAAmB;AACjD,kBAAM,IAAI,KAAK,aAAa,6DAA6D;AAAA,UAC1F;AACA,iBAAO,KAAK,SAAS,YAAY;AACjC,eAAK,aAAa;AAClB,eAAK,iBAAiB,4DAA4D,KAAK,OAAO;AAC9F,eAAK,OAAO,iBAAiB,MAAM,mBAAmB;AAAA,QACvD;AAAA,MACD;AAAA,MACA,aAAa,QAAQ,MAAM,MAAM;AAntEpC;AAotEI,eAAO,KAAK,YAAY;AACxB,aAAK,SAAS,WAAW,MAAM,IAAI;AACnC,iBAAS,KAAK,MAAM;AACpB,YAAI,CAAC,UAAW,CAAC,KAAK,SAAS,MAAM,KAAK,CAAC,KAAK,QAAQ,MAAM,GAAI;AACjE,cAAI,KAAK,SAAS,aAAa,cAAc;AAC5C,iBAAK,UAAU,oCAAoC,KAAK,SAAS,YAAY,eAAe,KAAK,iCAAiC;AAAA,UACnI;AACA,iBAAO,KAAK,MAAM,qBAAqB;AAAA,QACxC;AACA,mBAAK,UAAS,gBAAd,GAAc,cAAgB,CAAC;AAC/B,YAAI,KAAK,SAAS,MAAM,GAAG;AAC1B,cAAI,KAAK,SAAS,YAAY,cAAc;AAC3C,kBAAM,IAAI,KAAK,aAAa,yDAAyD;AAAA,UACtF;AACA,eAAK,SAAS,YAAY,eAAe;AACzC,eAAK,aAAa;AAClB,eAAK,iBAAiB,sDAAsD,KAAK,OAAO;AACxF,eAAK,OAAO,iBAAiB,MAAM,uBAAuB;AAAA,QAC3D,OAAO;AACN,cAAI,CAAC,KAAK,SAAS,YAAY,cAAc;AAC5C,kBAAM,IAAI,KAAK,aAAa,sDAAsD;AAAA,UACnF;AACA,iBAAO,KAAK,SAAS,YAAY;AACjC,eAAK,aAAa;AAClB,eAAK,iBAAiB,mDAAmD,KAAK,OAAO;AACrF,eAAK,OAAO,iBAAiB,MAAM,wBAAwB;AAAA,QAC5D;AAAA,MACD;AAAA,MACA,IAAI;AAAA,MACJ,OAAO;AACN,aAAK,MAAM,GAAG,KAAK,4BAA4B;AAAA,MAChD;AAAA,IACD;AAAA,EACD;AAAA,EACA,eAAe,QAAQ;AACtB,QAAI,CAAC,KAAK,aAAa;AAAG;AAC1B,QAAI,OAAO,SAAS,UAAU,GAAG;AAChC,aAAO,KAAK;AAAA,QACX;AAAA,MAWD;AAAA,IACD;AAEA,SAAK;AAAA,MACJ;AAAA,IA6BD;AAAA,EACD;AACD;AAEA,MAAM,eAAuC;AAAA,EAC5C,WAAS;AAAA,IACR,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,SAAS;AAAA,MACR,CAAC,MAAM,KAAK,SAAS,aAAa,eAAe,8BAA8B;AAAA,MAC/E,CAAC,OAAO,CAAC,KAAK,SAAS,aAAa,eAAe,+BAA+B;AAAA,IACnF;AAAA,EACD;AAAA,EACA,WAAS;AAAA,IACR,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,SAAS;AAAA,MACR,CAAC,MAAM,KAAK,SAAS,aAAa,cAAc,6BAA6B;AAAA,MAC7E,CAAC,OAAO,CAAC,KAAK,SAAS,aAAa,cAAc,8BAA8B;AAAA,IACjF;AAAA,EACD;AAAA,EACA,WAAS;AAAA,IACR,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,SAAS;AAAA,MACR,CAAC,SAAS,KAAK,SAAS,aAAa,gBAAgB,6BAA6B;AAAA,MAClF,CAAC,YAAY,CAAC,KAAK,SAAS,aAAa,gBAAgB,gCAAgC;AAAA,IAC1F;AAAA,EACD;AAAA,EACA,WAAS;AAAA,IACR,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,SAAS;AAAA,MACR,CAAC,MAAM,KAAK,SAAS,aAAa,qBAAqB,yBAAyB;AAAA,MAChF,CAAC,OAAO,CAAC,KAAK,SAAS,aAAa,qBAAqB,0BAA0B;AAAA,IACpF;AAAA,EACD;AAAA,EACA,WAAS;AAAA,IACR,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,SAAS;AAAA,MACR,CAAC,SAAS,KAAK,SAAS,aAAa,iBAAiB,8BAA8B;AAAA,MACpF,CAAC,YAAY,CAAC,KAAK,SAAS,aAAa,iBAAiB,iCAAiC;AAAA,IAC5F;AAAA,EACD;AAAA,EACA,WAAS;AAAA,IACR,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,SAAS,CAAC,OAAO,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,IAAI,IAAI,IAAI,IAAI,EAAE,EAAE;AAAA,MACnE,aACC;AAAA,QACC,GAAG;AAAA,QACH,aAAa,KAAK,SAAS,aAAa,qBAAqB,UAAU,6BAA6B;AAAA,MACrG;AAAA,IAEF;AAAA,EACD;AAAA,EACA,WAAS;AAAA,IACR,OAAO;AAAA,IACP,YAAY;AAAA,IACZ,SAAS;AAAA,MACR,CAAC,MAAM,KAAK,SAAS,aAAa,gBAAgB,+BAA+B;AAAA,MACjF,CAAC,OAAO,CAAC,KAAK,SAAS,aAAa,gBAAgB,gCAAgC;AAAA,IACrF;AAAA,EACD;AACD;AAEO,MAAM,cAAc;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACD;AAEA,WAAW,QAAQ,MAAM,MAAM,OAAO,GAAG;AACxC,QAAM,gBAAiB,KAAK,SAAiB;AAC7C,SAAQ,KAAK,SAAiB;AAC9B,MAAI,CAAC,eAAe;AACnB,SAAK,aAAa;AAClB;AAAA,EACD;AACA,MAAI,CAAC,KAAK,SAAS;AAAa,SAAK,SAAS,cAAc,CAAC;AAC7D,OAAK,SAAS,YAAY,gBAAgB;AAC1C,OAAK,aAAa;AACnB;", "names": [] }