Files
galaxy-game/ui/frontend/src/lib/i18n/locales/en.ts
T
Ilia Denisov cfbe052242
Tests · UI / test (push) Successful in 2m45s
Tests · UI / test (pull_request) Successful in 2m52s
feat(ui): F8-09 — turn report sticky icon-popup section menu (#52)
- Replace the 14 rem sticky sidebar (and its mobile <select> twin)
  with a single sticky icon-popup trigger pinned to the top-right
  corner of the report column. Trigger shows `≡` followed by the
  currently active section title (CSS-clamped with text-overflow:
  ellipsis so long RU titles cannot bloat the button). Click opens
  an anchored popover on desktop and a fixed bottom-sheet on
  <768.98 px (mirrors lib/active-view/map-toggles.svelte).
- Each menuitem closes the popover and scrolls the matching
  `<section id="report-<slug>">` into view. The scroll is deferred
  one animation frame so the surface unmount + restoreFocus's
  focus restoration on the (sticky) trigger commit first; otherwise
  the focus call could cancel the just-started smooth/instant
  scroll under desktop Chromium and WebKit.
- Drop the in-report "Back to map" button — the same affordance
  lives in the app-shell view menu (tests/e2e/game-shell.spec.ts
  covers it).
- Tighten the report grid to a single flex column so the section
  body now occupies the full container width.
- i18n: remove game.report.back_to_map and
  game.report.toc.mobile_label; add game.report.toc.open and
  game.report.toc.close (mirrors game.map.toggles.open/close).
- Tests: Vitest report-toc.test.ts rewritten for the new icon-popup
  contract; Playwright report-sections.spec.ts switches the anchor
  loop to trigger → menuitem and adds a mobile bottom-sheet
  assertion; game-shell-stubs.test.ts no longer asserts the
  back-to-map button on the report orchestrator.
- Docs: ui/docs/report-view.md (TOC + i18n + test seams) and
  docs/FUNCTIONAL{,_ru}.md §6.4 updated. The stale SvelteKit
  Snapshot reference (the route file was removed by the single-URL
  app-shell) is dropped at the same time.

Refs: #52 (#43 umbrella).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 18:11:00 +02:00

766 lines
45 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// English translation dictionary. Keys are dotted strings grouped
// by feature area (`login.*`, `lobby.*`, `common.*`); values are
// the user-visible text. Adding a new key here also requires adding
// it to every other locale dictionary in this folder, otherwise the
// `t()` helper falls back to English at runtime.
const en = {
"common.language": "language",
"common.loading": "loading…",
"common.dismiss": "dismiss",
"common.skip_to_content": "skip to main content",
"common.retry": "retry",
"common.browser_not_supported_title": "browser not supported",
"common.browser_not_supported_body":
"Galaxy requires Ed25519 in WebCrypto. See supported browsers.",
"error.offline":
"You appear to be offline. Check your connection and try again.",
"error.network": "Couldn't reach the server. Please try again.",
"error.auth": "Your session has expired. Please sign in again.",
"error.forbidden": "You don't have permission to do that.",
"error.conflict":
"This changed since you loaded it. Refresh and try again.",
"error.not_found": "Not found — it may have been removed.",
"error.rate_limit": "Too many requests. Wait a moment and try again.",
"error.server": "The server ran into a problem. Please try again.",
"error.unknown": "Something went wrong.",
"game.events.turn_ready.message": "turn {turn} is ready",
"game.events.turn_ready.action": "view now",
"game.events.signature_failed": "verification failed, reconnecting…",
"game.events.unavailable.message": "this game is no longer available",
"login.title": "sign in to Galaxy",
"login.email_label": "email",
"login.email_required": "email must not be empty",
"login.send_code": "send code",
"login.sending": "sending…",
"login.code_label": "code",
"login.code_required": "code must not be empty",
"login.code_sent_to": "code sent to {email}",
"login.verify": "verify",
"login.verifying": "verifying…",
"login.send_new_code": "send a new code",
"login.change_email": "change email",
"login.challenge_expired":
"challenge expired, please request a new code",
"login.code_expired_or_used":
"code expired or already used, please request a new one",
"login.device_key_not_ready":
"device key is not ready, please reload the page",
"lobby.account_loading": "loading account…",
"lobby.logout": "logout",
"lobby.nav.aria_label": "lobby pages",
"lobby.nav.overview": "Overview",
"lobby.nav.profile": "Profile",
"lobby.nav.games": "games",
"lobby.nav.games.active_past": "active & past",
"lobby.nav.games.recruitment": "recruitment",
"lobby.nav.games.invitations": "invitations",
"lobby.nav.games.private_games": "private games",
"lobby.nav.games.aria_label": "games sections",
"lobby.nav.games.mobile_toggle": "games · {label}",
"lobby.nav.synthetic_reports": "Synthetic test reports",
"lobby.section.my_games": "my games",
"lobby.section.invitations": "pending invitations",
"lobby.section.applications": "my applications",
"lobby.section.public_games": "public games",
"lobby.section.recruitment": "open recruitment",
"lobby.section.private_games": "my private games",
"lobby.section.create": "create a game",
"lobby.create_button": "create new game",
"lobby.my_games.empty": "no games yet",
"lobby.invitations.empty": "no invitations",
"lobby.applications.empty": "no applications",
"lobby.public_games.empty": "no public games",
"lobby.games.active_past.empty": "no active or past games",
"lobby.games.private_games.empty": "no private games yet",
"lobby.recruitment.empty": "no open recruitment",
"lobby.recruitment.applied_pending": "your application is awaiting approval",
"lobby.recruitment.applied_approved": "your application was accepted",
"lobby.invitation.accept": "accept",
"lobby.invitation.decline": "decline",
"lobby.application.submit": "submit application",
"lobby.application.submit_for": "join {name}",
"lobby.application.race_name_label": "race name",
"lobby.application.race_name_required": "race name must not be empty",
"lobby.application.cancel": "cancel",
"lobby.application.submitted": "application submitted, awaiting approval",
"lobby.application.status.pending": "pending",
"lobby.application.status.approved": "approved",
"lobby.application.status.rejected": "rejected",
"lobby.application.status.unknown": "{status}",
"lobby.list_loading": "loading…",
"lobby.create.title": "create new game",
"lobby.create.game_name_label": "game name",
"lobby.create.description_label": "description",
"lobby.create.turn_schedule_label": "turn schedule",
"lobby.create.turn_schedule_hint": "five-field cron, e.g. 0 0 * * *",
"lobby.create.enrollment_ends_at_label": "enrollment ends at",
"lobby.create.advanced": "advanced",
"lobby.create.min_players_label": "min players",
"lobby.create.max_players_label": "max players",
"lobby.create.start_gap_hours_label": "start gap (hours)",
"lobby.create.start_gap_players_label": "start gap (players)",
"lobby.create.target_engine_version_label": "target engine version",
"lobby.create.submit": "create",
"lobby.create.submitting": "creating…",
"lobby.create.cancel": "cancel",
"lobby.create.game_name_required": "game name must not be empty",
"lobby.create.turn_schedule_required": "turn schedule must not be empty",
"lobby.create.enrollment_ends_at_required": "enrollment end time must be set",
"lobby.create.error.forbidden":
"Game creation is available only on a paid plan.",
"lobby.error.invalid_request": "request is invalid",
"lobby.error.subject_not_found": "not found",
"lobby.error.forbidden": "operation is forbidden",
"lobby.error.conflict": "request conflicts with current state",
"lobby.error.internal_error": "internal server error",
"lobby.error.unknown": "{message}",
"profile.title": "Profile",
"profile.loading": "loading account…",
"profile.field.user_name": "username",
"profile.field.email": "email",
"profile.field.display_name": "display name",
"profile.field.preferred_language": "preferred language",
"profile.field.time_zone": "time zone",
"profile.hint.display_name": "shown wherever Galaxy needs a friendlier name than the username handle. Leave empty to fall back to the username.",
"profile.hint.time_zone": "IANA zones grouped by continent. The form opens on your browser's current zone when no value is saved.",
"profile.save": "save",
"profile.saving": "saving…",
"profile.saved": "saved",
"profile.cancel": "cancel",
"profile.error.language_required": "language must not be empty",
"profile.error.time_zone_required": "time zone must not be empty",
"game.shell.unknown": "?",
"game.shell.connection.online": "online",
"game.shell.connection.reconnecting": "reconnecting…",
"game.shell.connection.offline": "offline",
"game.shell.menu.toggle_sidebar": "open sidebar",
"game.shell.menu.close_sidebar": "close sidebar",
"game.shell.menu.open_views": "open views menu",
"game.shell.menu.close_views": "close views menu",
"game.shell.menu.return_to_lobby": "return to lobby",
"game.shell.theme_toggle.to_light": "switch to light theme",
"game.shell.theme_toggle.to_dark": "switch to dark theme",
"game.shell.coming_soon": "coming soon",
"game.shell.turn.label": "turn {turn}",
"game.shell.turn.list_item": "turn #{turn}",
"game.shell.turn.prev": "previous turn",
"game.shell.turn.next": "next turn",
"game.shell.turn.open_navigator": "open turn list",
"game.shell.turn.close_navigator": "close turn list",
"game.shell.history.viewing": "Viewing turn {turn} · read-only",
"game.shell.history.return_to_current": "Return to current turn",
"game.shell.history.current_badge": "current",
"game.view.map": "map",
"game.map.toggles.open": "open map visibility menu",
"game.map.aria_label":
"galaxy map ({count} planets) — a visual overview; planet, ship-group and route details are available in the sidebar inspector and the tables view",
"game.map.toggles.close": "close map visibility menu",
"game.map.toggles.section.objects": "Objects",
"game.map.toggles.section.planets": "Planets",
"game.map.toggles.section.view": "View",
"game.map.toggles.hyperspace_groups": "hyperspace groups",
"game.map.toggles.incoming_groups": "incoming groups",
"game.map.toggles.unidentified_groups": "unidentified groups",
"game.map.toggles.cargo_routes": "cargo routes",
"game.map.toggles.battle_markers": "battle markers",
"game.map.toggles.bombing_markers": "bombing markers",
"game.map.toggles.foreign_planets": "foreign planets",
"game.map.toggles.uninhabited_planets": "uninhabited planets",
"game.map.toggles.unidentified_planets": "unidentified planets",
"game.map.toggles.unreachable_planets": "show unreachable planets",
"game.map.toggles.visible_hyperspace": "visible hyperspace",
"game.view.table": "table",
"game.view.table.planets": "planets",
"game.view.table.ship_classes": "ship classes",
"game.view.table.ship_groups": "ship groups",
"game.view.table.fleets": "fleets",
"game.view.table.sciences": "sciences",
"game.view.table.races": "races",
"game.view.report": "turn report",
"game.view.battle": "battle log",
"game.view.mail": "diplomatic mail",
"game.view.mail.badge": "{count}",
"game.events.mail_new.message": "new mail from {from}",
"game.events.mail_new.action": "view",
"game.mail.loading": "loading mail…",
"game.mail.load_failed": "could not load mail",
"game.mail.empty": "no diplomatic messages yet",
"game.mail.back": "back",
"game.mail.compose_action": "compose",
"game.mail.select_thread": "pick a thread on the left to read it",
"game.mail.broadcast.title": "your broadcast",
"game.mail.admin.title": "admin notification",
"game.mail.system.generic.title": "system message",
"game.mail.system.game_paused.title": "game paused",
"game.mail.system.game_cancelled.title": "game cancelled",
"game.mail.system.membership_removed.title": "membership removed",
"game.mail.system.membership_blocked.title": "membership blocked",
"game.mail.subject_placeholder": "subject (optional)",
"game.mail.body_placeholder": "your message…",
"game.mail.recipient_label": "race",
"game.mail.recipient_required": "pick a recipient race",
"game.mail.body_required": "the message body cannot be empty",
"game.mail.body_too_long": "the body exceeds the {limit} byte limit",
"game.mail.subject_too_long": "the subject exceeds the {limit} byte limit",
"game.mail.compose.send": "send",
"game.mail.compose.cancel": "cancel",
"game.mail.compose.target_personal": "personal",
"game.mail.compose.target_broadcast": "broadcast",
"game.mail.compose.target_admin": "admin",
"game.mail.compose.recipients_active": "active members",
"game.mail.compose.recipients_active_and_removed": "active + removed",
"game.mail.compose.recipients_all_members": "all members",
"game.mail.compose.target_label": "kind",
"game.mail.compose.recipients_label": "audience",
"game.mail.compose.send_failed": "send failed",
"game.mail.show_original": "show original",
"game.mail.show_translation": "show translation",
"game.mail.translation_unavailable": "translation unavailable",
"game.mail.reply_label": "reply",
"game.mail.delete_action": "delete",
"game.mail.outgoing_label": "you",
"game.view.designer.ship_class": "ship-class designer",
"game.view.designer.science": "science designer",
"game.sidebar.tab.calculator": "calculator",
"game.sidebar.tab.inspector": "inspector",
"game.sidebar.tab.order": "order",
"game.sidebar.empty.calculator": "coming soon",
"game.sidebar.empty.inspector": "select an object on the map",
"game.sidebar.empty.order": "order is empty",
"game.sidebar.order.command_delete": "delete",
"game.sidebar.order.sync.idle": "no changes yet",
"game.sidebar.order.sync.in_flight": "syncing…",
"game.sidebar.order.sync.synced": "synced with server",
"game.sidebar.order.sync.error": "sync failed: {message}",
"game.sidebar.order.sync.offline": "queued — offline, will retry on reconnect",
"game.sidebar.order.sync.conflict": "turn closed before submit",
"game.sidebar.order.sync.paused": "game paused — orders disabled",
"game.sidebar.order.sync.retry": "retry",
"game.sidebar.order.conflict.banner": "Turn {turn} closed before your order was accepted. Edit and resubmit.",
"game.sidebar.order.conflict.banner_no_turn": "Turn closed before your order was accepted. Edit and resubmit.",
"game.sidebar.order.paused.banner": "Game paused. Orders are not accepted until it resumes.",
"game.sidebar.order.status.draft": "draft",
"game.sidebar.order.status.valid": "valid",
"game.sidebar.order.status.invalid": "invalid",
"game.sidebar.order.status.submitting": "submitting",
"game.sidebar.order.status.applied": "applied",
"game.sidebar.order.status.rejected": "rejected",
"game.sidebar.order.status.conflict": "conflict",
"game.sidebar.order.label.placeholder": "{label}",
"game.sidebar.order.label.planet_rename": "rename planet {planet} → {name}",
"game.sidebar.order.label.planet_production": "set production on planet {planet} → {target}",
"game.bottom_tabs.map": "map",
"game.bottom_tabs.calc": "calc",
"game.bottom_tabs.order": "order",
"game.bottom_tabs.more": "more",
"game.inspector.planet.kind.local": "your planet",
"game.inspector.planet.kind.other": "other race planet",
"game.inspector.planet.kind.uninhabited": "uninhabited planet",
"game.inspector.planet.kind.unidentified": "unidentified planet",
"game.inspector.planet.field.name": "name",
"game.inspector.planet.field.owner": "owner",
"game.inspector.planet.field.coordinates": "coordinates",
"game.inspector.planet.field.size": "size",
"game.inspector.planet.field.population": "population",
"game.inspector.planet.field.colonists": "colonists",
"game.inspector.planet.field.industry": "industry",
"game.inspector.planet.field.industry_stockpile": "industry ($)",
"game.inspector.planet.field.materials_stockpile": "materials (M)",
"game.inspector.planet.field.natural_resources": "natural resources",
"game.inspector.planet.field.production": "current production",
"game.inspector.planet.field.free_industry": "free production",
"game.inspector.planet.production_none": "none",
"game.inspector.planet.unidentified_no_data": "no data — only the location is known",
"game.inspector.sheet_close": "close",
"game.inspector.planet.action.rename": "rename",
"game.inspector.planet.rename.title": "rename planet",
"game.inspector.planet.rename.confirm": "save",
"game.inspector.planet.rename.invalid.empty": "name cannot be empty",
"game.inspector.planet.rename.invalid.too_long": "name is too long (30 characters max)",
"game.inspector.planet.rename.invalid.starts_with_special": "name cannot start with a special character",
"game.inspector.planet.rename.invalid.ends_with_special": "name cannot end with a special character",
"game.inspector.planet.rename.invalid.consecutive_specials": "too many special characters in a row",
"game.inspector.planet.rename.invalid.whitespace": "name cannot contain spaces",
"game.inspector.planet.rename.invalid.disallowed_character": "name contains disallowed characters",
"game.inspector.planet.production.title": "production",
"game.inspector.planet.production.main.aria": "production type",
"game.inspector.planet.production.option.industry": "industry",
"game.inspector.planet.production.option.materials": "materials",
"game.inspector.planet.production.option.research": "research",
"game.inspector.planet.production.option.ship": "build ship",
"game.inspector.planet.production.research.drive": "drive",
"game.inspector.planet.production.research.weapons": "weapons",
"game.inspector.planet.production.research.shields": "shields",
"game.inspector.planet.production.research.cargo": "cargo",
"game.inspector.planet.production.target.research.aria": "research target",
"game.inspector.planet.production.target.research.placeholder": "(tech or science)",
"game.inspector.planet.production.target.ship.aria": "ship class",
"game.inspector.planet.production.target.ship.placeholder": "(ship class)",
"game.inspector.planet.production.ship.no_classes": "no ship classes designed yet",
"game.inspector.planet.production.apply": "apply production change",
"game.inspector.planet.production.cancel": "discard production change",
"game.inspector.planet.cargo.placeholder": "manage routes",
"game.inspector.planet.cargo.slot.col": "colonists",
"game.inspector.planet.cargo.slot.cap": "industry",
"game.inspector.planet.cargo.slot.mat": "materials",
"game.inspector.planet.cargo.slot.emp": "empty ships",
"game.inspector.planet.cargo.empty": "(no route)",
"game.inspector.planet.cargo.add": "add",
"game.inspector.planet.cargo.edit": "edit",
"game.inspector.planet.cargo.remove": "remove",
"game.inspector.planet.cargo.pick.prompt": "pick a destination on the map (Esc to cancel)",
"game.inspector.planet.cargo.pick.cancel": "cancel pick",
"game.inspector.planet.cargo.pick.no_destinations": "no reachable destinations within {reach} world units",
"game.sidebar.order.label.cargo_route_set": "set {loadType} route from planet {source} → planet {destination}",
"game.sidebar.order.label.cargo_route_remove": "remove {loadType} route from planet {source}",
"game.sidebar.order.label.ship_class_create": "design ship class {name}",
"game.sidebar.order.label.ship_class_remove": "remove ship class {name}",
"game.sidebar.order.label.science_create": "define science {name}",
"game.sidebar.order.label.science_remove": "remove science {name}",
"game.sidebar.order.label.ship_group_break": "split group {group} → {quantity} ships into new group",
"game.sidebar.order.label.ship_group_send": "send group {group} → planet {destination}",
"game.sidebar.order.label.ship_group_load": "load {cargo} × {quantity} onto group {group}",
"game.sidebar.order.label.ship_group_unload": "unload × {quantity} from group {group}",
"game.sidebar.order.label.ship_group_upgrade": "modernize group {group} {tech} → {level}",
"game.sidebar.order.label.ship_group_dismantle": "dismantle group {group}",
"game.sidebar.order.label.ship_group_transfer": "transfer group {group} → {acceptor}",
"game.sidebar.order.label.ship_group_join_fleet": "assign group {group} → fleet {fleet}",
"game.sidebar.order.label.race_relation": "declare {relation} on {acceptor}",
"game.sidebar.order.label.race_vote": "give my votes to {acceptor}",
"game.table.ship_classes.title": "ship classes",
"game.table.ship_classes.column.name": "name",
"game.table.ship_classes.column.drive": "drive",
"game.table.ship_classes.column.armament": "armament",
"game.table.ship_classes.column.weapons": "weapons",
"game.table.ship_classes.column.shields": "shields",
"game.table.ship_classes.column.cargo": "cargo",
"game.table.ship_classes.column.actions": "actions",
"game.table.ship_classes.empty": "no ship classes designed yet",
"game.table.ship_classes.filter.placeholder": "filter by name",
"game.table.ship_classes.action.new": "+ new ship class",
"game.table.ship_classes.action.delete": "delete",
"game.table.ship_classes.loading": "loading ship classes…",
"game.designer.ship_class.title.new": "design new ship class",
"game.designer.ship_class.title.view": "ship class {name}",
"game.designer.ship_class.field.name": "name",
"game.designer.ship_class.field.drive": "drive",
"game.designer.ship_class.field.armament": "armament",
"game.designer.ship_class.field.weapons": "weapons",
"game.designer.ship_class.field.shields": "shields",
"game.designer.ship_class.field.cargo": "cargo",
"game.designer.ship_class.action.save": "save",
"game.designer.ship_class.action.cancel": "cancel",
"game.designer.ship_class.action.delete": "delete",
"game.designer.ship_class.action.back": "back",
"game.designer.ship_class.hint.values": "each value is either 0 or ≥ 1; armament is a non-negative integer; armament and weapons are both zero or both nonzero",
"game.designer.ship_class.read_only_notice": "ship classes are designed once; values cannot be edited after creation",
"game.designer.ship_class.not_found": "ship class \"{name}\" does not exist",
"game.designer.ship_class.invalid.empty": "name cannot be empty",
"game.designer.ship_class.invalid.too_long": "name is too long (30 characters max)",
"game.designer.ship_class.invalid.starts_with_special": "name cannot start with a special character",
"game.designer.ship_class.invalid.ends_with_special": "name cannot end with a special character",
"game.designer.ship_class.invalid.consecutive_specials": "too many special characters in a row",
"game.designer.ship_class.invalid.whitespace": "name cannot contain spaces",
"game.designer.ship_class.invalid.disallowed_character": "name contains disallowed characters",
"game.designer.ship_class.invalid.duplicate_name": "a ship class with this name already exists",
"game.designer.ship_class.invalid.drive_value": "drive must be 0 or ≥ 1",
"game.designer.ship_class.invalid.armament_value": "armament must be 0 or a positive integer",
"game.designer.ship_class.invalid.armament_not_integer": "armament must be an integer",
"game.designer.ship_class.invalid.weapons_value": "weapons must be 0 or ≥ 1",
"game.designer.ship_class.invalid.shields_value": "shields must be 0 or ≥ 1",
"game.designer.ship_class.invalid.cargo_value": "cargo must be 0 or ≥ 1",
"game.designer.ship_class.invalid.armament_weapons_pair": "armament and weapons must be both zero or both nonzero",
"game.designer.ship_class.invalid.all_zero": "at least one value must be nonzero",
"game.designer.ship_class.preview.title": "preview at your tech levels",
"game.designer.ship_class.preview.mass": "mass",
"game.designer.ship_class.preview.full_load_mass": "full-load mass",
"game.designer.ship_class.preview.max_speed": "max speed (ly/turn)",
"game.designer.ship_class.preview.range": "range at full load (ly/turn)",
"game.designer.ship_class.preview.cargo_capacity": "cargo capacity per ship",
"game.designer.ship_class.preview.unavailable": "—",
"game.calculator.title": "ship class calculator",
"game.calculator.mode.ship": "calculator",
"game.calculator.mode.modernization": "modernization",
"game.calculator.name.placeholder": "new class name",
"game.calculator.name.existing": "your ship classes",
"game.calculator.action.create": "create",
"game.calculator.col.ship": "ship",
"game.calculator.col.tech": "tech",
"game.calculator.field.drive": "drive",
"game.calculator.field.armament": "armament",
"game.calculator.field.weapons": "weapons",
"game.calculator.field.shields": "shields",
"game.calculator.field.cargo": "cargo",
"game.calculator.load.label": "load",
"game.calculator.load.empty": "empty",
"game.calculator.load.full": "full",
"game.calculator.load.custom": "custom",
"game.calculator.col.empty": "empty",
"game.calculator.col.loaded": "loaded",
"game.calculator.out.mass": "mass",
"game.calculator.out.speed": "speed",
"game.calculator.out.attack": "attack",
"game.calculator.out.defense": "defense",
"game.calculator.out.bombing": "bombing",
"game.calculator.out.cargo_capacity": "cargo capacity",
"game.calculator.planet.title": "planet",
"game.calculator.planet.none": "select one of your planets on the map",
"game.calculator.planet.label": "planet {name} (#{number})",
"game.calculator.planet.mat": "MAT",
"game.calculator.planet.ships_per_turn": "ships / turn",
"game.calculator.planet.turns_per_ship": "turns / ship",
"game.calculator.lock.reset": "locked — click to release to the computed value",
"game.calculator.lock.infeasible": "this target cannot be reached with the current design",
"game.calculator.lock.max": "release the locked result first — one result at a time",
"game.calculator.tech.override": "click to override your current tech",
"game.calculator.tech.reset": "overridden — click to reset to your current tech",
"game.calculator.mat.override": "click to override the planet value",
"game.calculator.mat.reset": "overridden — click to reset to the planet value",
"game.calculator.modern.current": "current",
"game.calculator.modern.target": "target",
"game.calculator.modern.cost": "upgrade cost",
"game.calculator.modern.total": "total upgrade cost",
"game.calculator.unavailable": "—",
"game.calculator.invalid.empty": "name cannot be empty",
"game.calculator.invalid.too_long": "name is too long (30 characters max)",
"game.calculator.invalid.starts_with_special": "name cannot start with a special character",
"game.calculator.invalid.ends_with_special": "name cannot end with a special character",
"game.calculator.invalid.consecutive_specials": "too many special characters in a row",
"game.calculator.invalid.whitespace": "name cannot contain spaces",
"game.calculator.invalid.disallowed_character": "name contains disallowed characters",
"game.calculator.invalid.duplicate_name": "a ship class with this name already exists",
"game.calculator.invalid.drive_value": "drive must be 0 or ≥ 1",
"game.calculator.invalid.armament_value": "armament must be 0 or a positive integer",
"game.calculator.invalid.armament_not_integer": "armament must be an integer",
"game.calculator.invalid.weapons_value": "weapons must be 0 or ≥ 1",
"game.calculator.invalid.shields_value": "shields must be 0 or ≥ 1",
"game.calculator.invalid.cargo_value": "cargo must be 0 or ≥ 1",
"game.calculator.invalid.armament_weapons_pair": "armament and weapons must be both zero or both nonzero",
"game.calculator.invalid.all_zero": "at least one value must be nonzero",
"game.calculator.invalid.negative": "value cannot be negative",
"game.calculator.invalid.tech_value": "tech level cannot be negative",
"game.calculator.invalid.tech_below_current": "tech level cannot be below your current tech this turn",
"game.calculator.invalid.load_over_capacity": "load exceeds the ship's cargo capacity",
"game.calculator.lock.no_drive": "set a non-zero drive before locking speed",
"game.calculator.confirm_reset_for_load": "Discard unsaved changes and load class «{name}»?",
"game.table.sciences.title": "sciences",
"game.table.sciences.column.name": "name",
"game.table.sciences.column.drive": "drive %",
"game.table.sciences.column.weapons": "weapons %",
"game.table.sciences.column.shields": "shields %",
"game.table.sciences.column.cargo": "cargo %",
"game.table.sciences.column.actions": "actions",
"game.table.sciences.empty": "no sciences defined yet",
"game.table.sciences.filter.placeholder": "filter by name",
"game.table.sciences.action.new": "+ new science",
"game.table.sciences.action.delete": "delete",
"game.table.sciences.loading": "loading sciences…",
"game.designer.science.title.new": "define new science",
"game.designer.science.title.view": "science {name}",
"game.designer.science.field.name": "name",
"game.designer.science.field.drive": "drive %",
"game.designer.science.field.weapons": "weapons %",
"game.designer.science.field.shields": "shields %",
"game.designer.science.field.cargo": "cargo %",
"game.designer.science.field.sum": "sum: {value} % (must equal 100)",
"game.designer.science.action.save": "save",
"game.designer.science.action.cancel": "cancel",
"game.designer.science.action.delete": "delete",
"game.designer.science.action.back": "back",
"game.designer.science.hint.values": "each value is a percent in [0, 100] with one decimal; the four percentages must sum to exactly 100",
"game.designer.science.read_only_notice": "sciences are defined once; values cannot be edited after creation",
"game.designer.science.not_found": "science \"{name}\" does not exist",
"game.designer.science.invalid.empty": "name cannot be empty",
"game.designer.science.invalid.too_long": "name is too long (30 characters max)",
"game.designer.science.invalid.starts_with_special": "name cannot start with a special character",
"game.designer.science.invalid.ends_with_special": "name cannot end with a special character",
"game.designer.science.invalid.consecutive_specials": "too many special characters in a row",
"game.designer.science.invalid.whitespace": "name cannot contain spaces",
"game.designer.science.invalid.disallowed_character": "name contains disallowed characters",
"game.designer.science.invalid.duplicate_name": "a science with this name already exists",
"game.designer.science.invalid.drive_value": "drive % must be in [0, 100]",
"game.designer.science.invalid.weapons_value": "weapons % must be in [0, 100]",
"game.designer.science.invalid.shields_value": "shields % must be in [0, 100]",
"game.designer.science.invalid.cargo_value": "cargo % must be in [0, 100]",
"game.designer.science.invalid.sum_not_hundred": "the four percentages must sum to exactly 100",
"game.table.races.title": "races",
"game.table.races.loading": "loading races…",
"game.table.races.empty": "no other races known yet",
"game.table.races.filter.placeholder": "filter by name",
"game.table.races.column.name": "name",
"game.table.races.column.drive": "drive",
"game.table.races.column.weapons": "weapons",
"game.table.races.column.shields": "shields",
"game.table.races.column.cargo": "cargo",
"game.table.races.column.population": "population",
"game.table.races.column.industry": "production",
"game.table.races.column.planets": "planets",
"game.table.races.column.votes": "votes received",
"game.table.races.column.relation": "stance",
"game.table.races.action.war": "WAR",
"game.table.races.action.peace": "PEACE",
"game.table.races.votes.mine": "my votes",
"game.table.races.votes.target": "I vote for",
"game.table.races.votes.target_placeholder": "— select a race —",
"game.table.races.note.alliance_server_side": "alliances and the 2/3 victory are tallied by the server at turn cutoff; this table shows only my outgoing vote and the votes each race received in the last tally",
"game.inspector.ship_group.kind.local": "your group",
"game.inspector.ship_group.kind.other": "other race group",
"game.inspector.ship_group.kind.incoming": "incoming group",
"game.inspector.ship_group.kind.unidentified": "unidentified group",
"game.inspector.ship_group.field.class": "class",
"game.inspector.ship_group.field.count": "ships",
"game.inspector.ship_group.field.drive": "drive",
"game.inspector.ship_group.field.weapons": "weapons",
"game.inspector.ship_group.field.shields": "shields",
"game.inspector.ship_group.field.cargo_tech": "cargo",
"game.inspector.ship_group.field.mass": "mass",
"game.inspector.ship_group.field.cargo_load": "cargo aboard",
"game.inspector.ship_group.field.location": "location",
"game.inspector.ship_group.field.from": "from",
"game.inspector.ship_group.field.to": "to",
"game.inspector.ship_group.field.distance": "distance remaining",
"game.inspector.ship_group.field.speed": "speed (ly/turn)",
"game.inspector.ship_group.field.eta": "ETA (turns)",
"game.inspector.ship_group.field.fleet": "fleet",
"game.inspector.ship_group.field.state": "state",
"game.inspector.ship_group.field.coordinates": "coordinates",
"game.inspector.ship_group.cargo.col": "colonists",
"game.inspector.ship_group.cargo.cap": "industry",
"game.inspector.ship_group.cargo.mat": "materials",
"game.inspector.ship_group.cargo.emp": "empty",
"game.inspector.ship_group.cargo.none": "none",
"game.inspector.ship_group.location.in_hyperspace": "in hyperspace",
"game.inspector.ship_group.fleet.none": "—",
"game.inspector.ship_group.unidentified_no_data": "no data — only the radar blip is known",
"game.inspector.ship_group.action.split": "split",
"game.inspector.ship_group.action.send": "send",
"game.inspector.ship_group.action.load": "load",
"game.inspector.ship_group.action.unload": "unload",
"game.inspector.ship_group.action.modernize": "modernize",
"game.inspector.ship_group.action.dismantle": "dismantle",
"game.inspector.ship_group.action.transfer": "transfer",
"game.inspector.ship_group.action.join_fleet": "join fleet",
"game.inspector.ship_group.action.confirm": "confirm",
"game.inspector.ship_group.action.cancel": "cancel",
"game.inspector.ship_group.action.confirm_destroy": "confirm — colonists die",
"game.inspector.ship_group.action.disabled.not_in_orbit": "ships are busy ({state}); only orbiting groups accept actions",
"game.inspector.ship_group.action.disabled.no_reach": "no planets are within drive range",
"game.inspector.ship_group.action.disabled.no_drive": "this ship class has no drive block",
"game.inspector.ship_group.action.disabled.no_cargo_block": "this ship class has no cargo block",
"game.inspector.ship_group.action.disabled.no_planet": "the orbit planet is not visible",
"game.inspector.ship_group.action.disabled.foreign_planet": "this action is only available on your own or unowned planets",
"game.inspector.ship_group.action.disabled.empty_cargo": "the group is empty",
"game.inspector.ship_group.action.disabled.foreign_unload_col": "colonists cannot be unloaded over a foreign planet",
"game.inspector.ship_group.action.disabled.no_headroom": "the group's tech is already at your race level",
"game.inspector.ship_group.action.disabled.no_planet_stock": "the planet has no available stock of this cargo",
"game.inspector.ship_group.action.disabled.full_load": "the group is fully loaded",
"game.inspector.ship_group.action.disabled.no_other_races": "no other non-extinct races to transfer to",
"game.inspector.ship_group.action.disabled.unknown_class": "the ship class is missing from the report",
"game.inspector.ship_group.action.disabled.locked": "an order is already queued for this group; cancel it in the order list to issue a new one",
"game.inspector.ship_group.action.locked.banner": "an order is already queued for this group: {command}. Cancel it in the order list to issue another action.",
"game.inspector.ship_group.action.locked.kind.send": "send",
"game.inspector.ship_group.action.locked.kind.modernize": "modernize",
"game.inspector.ship_group.action.locked.kind.dismantle": "dismantle",
"game.inspector.ship_group.action.locked.kind.transfer": "transfer",
"game.inspector.ship_group.action.field.ships": "ships ({max} total)",
"game.inspector.ship_group.action.field.cargo": "cargo type",
"game.inspector.ship_group.action.field.quantity": "quantity",
"game.inspector.ship_group.action.field.level": "tech level",
"game.inspector.ship_group.action.field.tech": "tech",
"game.inspector.ship_group.action.field.acceptor": "acceptor",
"game.inspector.ship_group.action.field.fleet": "fleet name",
"game.inspector.ship_group.action.field.destination": "destination planet",
"game.inspector.ship_group.action.tech.all": "all blocks",
"game.inspector.ship_group.action.tech.drive": "drive",
"game.inspector.ship_group.action.tech.weapons": "weapons",
"game.inspector.ship_group.action.tech.shields": "shields",
"game.inspector.ship_group.action.tech.cargo": "cargo",
"game.inspector.ship_group.action.send.pick_prompt": "click a planet on the map (Esc to cancel)",
"game.inspector.ship_group.action.modernize.cost": "estimated cost: {cost}",
"game.inspector.ship_group.action.modernize.cost_unavailable": "cost preview unavailable",
"game.inspector.ship_group.action.dismantle.warning": "the group is over a foreign planet with colonists aboard — they will die",
"game.inspector.ship_group.action.fleet.create_new": "+ new fleet",
"game.inspector.ship_group.action.invalid.ship_count": "ships must be in the range 1…{max}",
"game.inspector.ship_group.action.invalid.quantity": "quantity must be greater than zero",
"game.inspector.ship_group.action.invalid.level": "level must be in ({current}, {max}]",
"game.inspector.ship_group.action.invalid.fleet_name": "fleet name does not match the entity-name rules",
"game.inspector.planet.ship_groups.race_filter.aria": "stationed race",
"game.inspector.planet.ship_groups.title": "stationed ship groups",
"game.inspector.planet.ship_groups.race.unknown": "unknown",
"game.report.loading": "loading report…",
"game.report.toc.title": "sections",
"game.report.toc.open": "show section list",
"game.report.toc.close": "hide section list",
"game.report.section.galaxy_summary.title": "galaxy summary",
"game.report.section.galaxy_summary.field.turn": "turn",
"game.report.section.galaxy_summary.field.size": "map size",
"game.report.section.galaxy_summary.field.planets": "planet count",
"game.report.section.galaxy_summary.field.race": "your race",
"game.report.section.votes.title": "votes",
"game.report.section.votes.mine": "my votes",
"game.report.section.votes.target": "I vote for",
"game.report.section.votes.target_none": "(no recipient yet)",
"game.report.section.votes.received_header": "votes received last tally",
"game.report.section.votes.column.race": "race",
"game.report.section.votes.column.votes": "votes received",
"game.report.section.votes.empty": "no votes cast yet",
"game.report.section.player_status.title": "player status",
"game.report.section.player_status.column.name": "name",
"game.report.section.player_status.column.drive": "drive",
"game.report.section.player_status.column.weapons": "weapons",
"game.report.section.player_status.column.shields": "shields",
"game.report.section.player_status.column.cargo": "cargo",
"game.report.section.player_status.column.population": "population",
"game.report.section.player_status.column.industry": "production",
"game.report.section.player_status.column.planets": "planets",
"game.report.section.player_status.column.votes": "votes received",
"game.report.section.player_status.local_marker": "you",
"game.report.section.player_status.extinct_marker": "RIP",
"game.report.section.my_sciences.title": "my sciences",
"game.report.section.my_sciences.column.name": "name",
"game.report.section.my_sciences.column.drive": "drive %",
"game.report.section.my_sciences.column.weapons": "weapons %",
"game.report.section.my_sciences.column.shields": "shields %",
"game.report.section.my_sciences.column.cargo": "cargo %",
"game.report.section.my_sciences.empty": "no sciences defined yet",
"game.report.section.foreign_sciences.title": "foreign sciences",
"game.report.section.foreign_sciences.race_header": "{race} sciences",
"game.report.section.foreign_sciences.empty": "no foreign sciences observed yet",
"game.report.section.my_ship_classes.title": "my ship classes",
"game.report.section.my_ship_classes.column.name": "name",
"game.report.section.my_ship_classes.column.drive": "drive",
"game.report.section.my_ship_classes.column.armament": "armament",
"game.report.section.my_ship_classes.column.weapons": "weapons",
"game.report.section.my_ship_classes.column.shields": "shields",
"game.report.section.my_ship_classes.column.cargo": "cargo",
"game.report.section.my_ship_classes.empty": "no ship classes designed yet",
"game.report.section.foreign_ship_classes.title": "foreign ship classes",
"game.report.section.foreign_ship_classes.race_header": "{race} ship classes",
"game.report.section.foreign_ship_classes.column.mass": "mass",
"game.report.section.foreign_ship_classes.empty": "no foreign ship classes observed yet",
"game.report.section.battles.title": "battles",
"game.report.section.battles.empty": "no battles last turn",
"game.report.section.battles.id_label": "battle",
"game.battle.title": "battle",
"game.battle.header_title": "Battle on planet {planet_name} (#{planet_number})",
"game.battle.loading": "loading battle…",
"game.battle.not_found": "battle not found",
"game.battle.back_to_report": "back to report",
"game.battle.back_to_map": "back to map",
"game.battle.scene_label": "battle scene",
"game.battle.controls.play": "play",
"game.battle.controls.pause": "pause",
"game.battle.controls.step_forward": "step forward",
"game.battle.controls.step_backward": "step back",
"game.battle.controls.rewind": "rewind to start",
"game.battle.controls.speed_label": "speed",
"game.battle.controls.speed_1x": "1x",
"game.battle.controls.speed_2x": "2x",
"game.battle.controls.speed_4x": "4x",
"game.battle.controls.speed_6x": "6x",
"game.battle.controls.scrub": "scrub battle timeline",
"game.battle.controls.log_toggle": "Log",
"game.battle.log.destroyed": "{attacker_race}'s {attacker_class} destroyed {defender_race}'s {defender_class}",
"game.battle.log.shielded": "{attacker_race}'s {attacker_class} hit {defender_race}'s {defender_class}, shields held",
"game.battle.accessibility.protocol_heading": "battle log",
"game.report.section.bombings.title": "bombings",
"game.report.section.bombings.empty": "no bombings last turn",
"game.report.section.bombings.column.planet": "planet",
"game.report.section.bombings.column.owner": "owner",
"game.report.section.bombings.column.attacker": "attacker",
"game.report.section.bombings.column.production": "production",
"game.report.section.bombings.column.industry": "industry",
"game.report.section.bombings.column.population": "population",
"game.report.section.bombings.column.colonists": "colonists",
"game.report.section.bombings.column.industry_stockpile": "industry ($)",
"game.report.section.bombings.column.materials_stockpile": "materials (M)",
"game.report.section.bombings.column.attack_power": "attack power",
"game.report.section.bombings.wiped": "wiped",
"game.report.section.approaching_groups.title": "approaching groups",
"game.report.section.approaching_groups.empty": "no approaching groups",
"game.report.section.approaching_groups.column.from": "from",
"game.report.section.approaching_groups.column.to": "to",
"game.report.section.approaching_groups.column.distance": "distance",
"game.report.section.approaching_groups.column.speed": "speed",
"game.report.section.approaching_groups.column.mass": "mass",
"game.report.section.my_planets.title": "my planets",
"game.report.section.my_planets.empty": "no planets owned yet",
"game.report.section.my_planets.column.number": "#",
"game.report.section.my_planets.column.name": "name",
"game.report.section.my_planets.column.coordinates": "x, y",
"game.report.section.my_planets.column.size": "size",
"game.report.section.my_planets.column.resources": "resources",
"game.report.section.my_planets.column.population": "population",
"game.report.section.my_planets.column.industry": "production",
"game.report.section.my_planets.column.industry_stockpile": "$",
"game.report.section.my_planets.column.materials_stockpile": "M",
"game.report.section.my_planets.column.colonists": "colonists",
"game.report.section.my_planets.column.production": "current production",
"game.report.section.my_planets.column.free_industry": "free",
"game.report.section.ships_in_production.title": "ships in production",
"game.report.section.ships_in_production.empty": "no ships in production",
"game.report.section.ships_in_production.column.planet": "planet",
"game.report.section.ships_in_production.column.class": "class",
"game.report.section.ships_in_production.column.cost": "cost",
"game.report.section.ships_in_production.column.prod_used": "invested",
"game.report.section.ships_in_production.column.percent": "percent",
"game.report.section.ships_in_production.column.free": "free industry",
"game.report.section.cargo_routes.title": "cargo routes",
"game.report.section.cargo_routes.empty": "no cargo routes set",
"game.report.section.cargo_routes.column.source": "source",
"game.report.section.cargo_routes.column.load": "load type",
"game.report.section.cargo_routes.column.destination": "destination",
"game.report.section.foreign_planets.title": "foreign planets",
"game.report.section.foreign_planets.empty": "no foreign planets observed",
"game.report.section.foreign_planets.column.owner": "owner",
"game.report.section.uninhabited_planets.title": "uninhabited planets",
"game.report.section.uninhabited_planets.empty": "no uninhabited planets observed",
"game.report.section.unknown_planets.title": "unknown planets",
"game.report.section.unknown_planets.empty": "no unknown planets",
"game.report.section.my_fleets.title": "my fleets",
"game.report.section.my_fleets.empty": "no fleets created yet",
"game.report.section.my_fleets.column.name": "name",
"game.report.section.my_fleets.column.groups": "groups",
"game.report.section.my_fleets.column.state": "state",
"game.report.section.my_fleets.column.destination": "destination",
"game.report.section.my_fleets.column.origin": "origin",
"game.report.section.my_fleets.column.range": "range",
"game.report.section.my_fleets.column.speed": "speed",
"game.report.section.my_ship_groups.title": "my ship groups",
"game.report.section.my_ship_groups.empty": "no ship groups yet",
"game.report.section.my_ship_groups.column.id": "id",
"game.report.section.my_ship_groups.column.class": "class",
"game.report.section.my_ship_groups.column.count": "count",
"game.report.section.my_ship_groups.column.cargo": "cargo",
"game.report.section.my_ship_groups.column.state": "state",
"game.report.section.my_ship_groups.column.destination": "destination",
"game.report.section.my_ship_groups.column.origin": "origin",
"game.report.section.my_ship_groups.column.range": "range",
"game.report.section.my_ship_groups.column.speed": "speed",
"game.report.section.my_ship_groups.column.mass": "mass",
"game.report.section.my_ship_groups.column.fleet": "fleet",
"game.report.section.foreign_ship_groups.title": "foreign ship groups",
"game.report.section.foreign_ship_groups.empty": "no foreign ship groups observed",
"game.report.section.unidentified_groups.title": "unidentified groups",
"game.report.section.unidentified_groups.empty": "no unidentified groups",
"game.report.section.unidentified_groups.column.x": "x",
"game.report.section.unidentified_groups.column.y": "y",
} as const;
export default en;