// English message catalog (authoritative). Keys are flat dotted strings; ru.ts must // provide exactly the same keys (enforced by its type and a Vitest parity test). // {name} placeholders are filled by t(key, params). export const en = { 'app.title': 'Scrabble', 'common.back': 'Back', 'common.cancel': 'Cancel', 'common.ok': 'OK', 'common.close': 'Close', 'common.loading': 'Loading…', 'common.retry': 'Retry', 'common.you': 'You', 'common.save': 'Save', 'login.title': 'Sign in', 'login.guest': 'Play as guest', 'login.email': 'Email', 'login.emailPlaceholder': 'you@example.com', 'login.sendCode': 'Send code', 'login.codePlaceholder': '6-digit code', 'login.signIn': 'Sign in', 'login.codeSent': 'We sent a code to {email}.', 'lobby.activeGames': 'Active games', 'lobby.finishedGames': 'Finished games', 'lobby.noActive': 'No active games yet.', 'lobby.noFinished': 'No finished games yet.', 'lobby.new': 'New', 'lobby.stats': 'Stats', 'lobby.tournaments': 'Tourn.', 'lobby.profile': 'Profile', 'lobby.settings': 'Settings', 'lobby.about': 'About', 'lobby.yourTurn': 'Your turn', 'lobby.theirTurn': 'Their turn', 'lobby.vs': 'vs {opponents}', 'lobby.soon': 'Coming soon', 'new.title': 'New game', 'new.subtitle': 'Auto-match with another player', 'new.english': 'Scrabble', 'new.russian': 'Скрэббл', 'new.erudit': 'Erudite', 'new.find': 'Find a game', 'new.searching': 'Looking for an opponent…', 'new.rulesEnglish': '100 tiles · bingo +50', 'new.rulesRussian': '104 tiles · ё is a letter · bingo +50', 'new.rulesErudit': '131 tiles · ё = е · no centre ×2 · bonus +15', 'new.moveLimit': 'Move time: {n} h 00 min', 'game.bag': '{n} in the bag', 'game.bagEmpty': 'Bag is empty', 'game.hints': 'Hints {n}', 'game.yourTurn': 'Your turn', 'game.waiting': "Waiting for {name}", 'game.makeMove': 'Make move', 'game.reset': 'Reset', 'game.draw': 'Draw', 'game.skip': 'Skip', 'game.shuffle': 'Shuffle', 'game.hint': 'Hint', 'game.history': 'History', 'game.chat': 'Chat', 'game.checkWord': 'Check word', 'game.dropGame': 'Drop game', 'game.preview': 'Scores {n}', 'game.previewIllegal': 'Not a legal move', 'game.chooseBlank': 'Choose a letter for the blank', 'game.exchangeTitle': 'Select tiles to exchange', 'game.exchangeConfirm': 'Exchange {n}', 'game.confirmResign': 'Resign this game?', 'game.hintShown': 'Best move: {word} for {n}', 'game.over': 'Game over', 'game.won': 'You won', 'game.lost': 'You lost', 'game.tied': 'Draw', 'game.checkWordPrompt': 'Enter a word', 'game.wordLegal': '“{word}” is valid', 'game.wordIllegal': '“{word}” is not valid', 'game.complain': 'Disagree', 'game.complaintSent': 'Thanks, sent for review.', 'game.confirm': 'Ok', 'game.check': 'Check', 'game.checkWait': 'Please wait a moment.', 'game.noHintOptions': 'No options with your letters.', 'game.scores': 'Scores: {n}', 'result.victory': 'Victory', 'result.defeat': 'Defeat', 'result.draw': 'Draw', 'result.place2': 'II place', 'result.place3': 'III place', 'result.place4': 'IV place', 'result.yourMove': 'Your move', 'result.oppMove': "Opponent's move", 'chat.placeholder': 'Quick message…', 'chat.send': 'Send', 'chat.nudge': 'Waiting for your move!', 'chat.nudgeAction': 'Nudge', 'chat.awaitingReply': "Waiting for the opponent's reply", 'chat.empty': 'No messages yet.', 'chat.nudged': '{name} nudged you', 'profile.title': 'Profile', 'profile.language': 'Language', 'profile.timezone': 'Time zone', 'profile.hintBalance': 'Hint balance', 'profile.guest': 'Guest account', 'profile.edit': 'Edit profile', 'profile.displayName': 'Display name', 'profile.awayWindow': 'Away window', 'profile.awayHint': 'You are not auto-resigned during these hours.', 'profile.from': 'From', 'profile.to': 'To', 'profile.blockChat': 'Disable chat', 'profile.blockFriendRequests': 'Disable friend requests', 'profile.notificationsInAppOnly': 'Notifications in the app only', 'profile.email': 'Email', 'profile.bindEmail': 'Bind email', 'profile.emailCode': 'Confirmation code', 'profile.emailSent': 'We sent a code to {email}.', 'profile.emailBound': 'Email confirmed.', 'profile.saved': 'Profile saved.', 'profile.guestLocked': 'Sign in with email to manage your profile.', 'profile.linkAccount': 'Link an account', 'profile.linkTelegram': 'Link Telegram', 'profile.linked': 'Account linked.', 'profile.merged': 'Accounts merged.', 'profile.mergeTitle': 'Merge accounts?', 'profile.mergeBody': 'This identity already belongs to “{name}” ({games} games, {friends} friends).', 'profile.mergeIrreversible': 'Merging combines both accounts into this one and cannot be undone.', 'profile.mergeConfirm': 'Merge', 'settings.title': 'Settings', 'settings.theme': 'Theme', 'settings.themeAuto': 'Auto', 'settings.themeLight': 'Light', 'settings.themeDark': 'Dark', 'settings.language': 'Interface language', 'settings.boardStyle': 'Board style', 'settings.boardLabels': 'Bonus labels', 'settings.labelsBeginner': 'Beginner', 'settings.labelsClassic': 'Classic', 'settings.labelsNone': 'None', 'settings.boardLines': 'Grid lines', 'settings.reduceMotion': 'Reduce motion', 'about.title': 'About', 'about.description': 'A multiplatform Scrabble game.', 'about.version': 'Version {v}', 'landing.tagline': 'Play Scrabble with friends or a smart robot — in your browser or on Telegram.', 'landing.playTelegram': 'Play in Telegram', 'lang.en': 'English', 'lang.ru': 'Русский', 'error.not_your_turn': "It is not your turn.", 'error.nudge_own_turn': 'It is your turn — there is no one to nudge.', 'error.illegal_play': 'That is not a legal play.', 'error.hint_unavailable': 'No hints available.', 'error.no_hint_available': 'No options with your letters.', 'error.chat_rejected': 'Message rejected (too long or contains contact info).', 'error.nudge_too_soon': "Please don't rush your opponent so often.", 'error.chat_not_your_turn': 'You can chat only on your turn.', 'error.game_finished': 'This game is finished.', 'error.not_a_player': 'You are not a player in this game.', 'error.already_queued': 'You are already in the queue.', 'error.email_taken': 'That email belongs to another account.', 'error.code_invalid': 'Invalid or expired code.', 'error.invalid_email': 'Enter a valid email address.', 'error.invalid_config': 'Invalid game settings.', 'error.not_found': 'Not found.', 'error.session_invalid': 'Your session expired. Please sign in again.', 'error.unauthenticated': 'Please sign in.', 'error.rate_limited': 'Too many requests, slow down.', 'error.unavailable': 'Connection problem. Retrying…', 'error.internal': 'Something went wrong.', 'error.generic': 'Something went wrong.', 'lobby.invitations': 'Invitations', 'lobby.friends': 'Friends', 'friends.title': 'Friends', 'friends.yours': 'Your friends', 'friends.none': 'No friends yet.', 'friends.incoming': 'Friend requests', 'friends.accept': 'Accept', 'friends.decline': 'Decline', 'friends.unfriend': 'Remove', 'friends.block': 'Block', 'friends.add': 'Add a friend', 'friends.addFromGame': 'Add to friends', 'friends.requestSent': 'Friend request sent.', 'friends.getCode': 'Show my code', 'friends.codeHint': 'Give this code to a friend within 12 hours.', 'friends.codeExpires': 'Expires at {time}', 'friends.enterCode': 'Have a code? Add a friend', 'friends.codePlaceholder': '6-digit code', 'friends.redeem': 'Add', 'friends.copy': 'Copy', 'friends.codeCopied': 'Code copied.', 'friends.shareTelegram': 'Share via Telegram', 'friends.added': 'Added {name}.', 'friends.blockedList': 'Blocked players', 'friends.unblock': 'Unblock', 'friends.noneBlocked': 'No blocked players.', 'invitations.none': 'No invitations.', 'invitations.from': 'From {name}', 'invitations.with': 'With {names}', 'invitations.accept': 'Accept', 'invitations.decline': 'Decline', 'invitations.cancel': 'Cancel', 'invitations.waiting': 'Waiting for replies', 'new.auto': 'Quick match', 'new.withFriends': 'Play with friends', 'new.pickFriends': 'Choose who to invite', 'new.searchFriends': 'Search friends', 'new.gameType': 'Game type', 'new.invite': 'Send invitation', 'new.moveTime': 'Move time', 'new.hintsPerPlayer': 'Hints per player', 'new.invited': 'Invitation sent.', 'new.noFriends': 'Add friends first to invite them.', 'stats.title': 'Statistics', 'stats.wins': 'Wins', 'stats.losses': 'Losses', 'stats.draws': 'Draws', 'stats.played': 'Games', 'stats.winRate': 'Win rate', 'stats.maxGame': 'Best game', 'stats.maxWord': 'Best move', 'stats.guestHint': 'Sign in to track your statistics.', 'game.exportGcg': 'Export GCG', 'game.gcgActiveOnly': 'Available once the game is finished.', 'game.requestSent': 'Request sent', 'time.minutes': '{n} min', 'time.hours': '{n} h', 'error.self_relation': 'You cannot do that to yourself.', 'error.request_exists': 'A request or friendship already exists.', 'error.request_blocked': 'This player is not accepting requests.', 'error.request_not_found': 'No matching friend request.', 'error.no_shared_game': 'You can only add someone you have played with.', 'error.request_declined': 'This player declined your request.', 'error.friend_code_invalid': 'That friend code is invalid or expired.', 'error.invalid_invitation': 'Invalid invitation.', 'error.invitation_blocked': 'You cannot invite this player.', 'error.invitation_not_found': 'Invitation not found.', 'error.invitation_not_pending': 'This invitation is no longer open.', 'error.invitation_expired': 'This invitation has expired.', 'error.not_invited': 'You were not invited.', 'error.already_responded': 'You already responded.', 'error.not_inviter': 'Only the inviter can do that.', 'error.game_active': 'Available only after the game is finished.', 'error.invalid_profile': 'Some profile fields are invalid.', 'error.already_confirmed': 'This email is already confirmed.', } as const; export type MessageKey = keyof typeof en;