--[[
    Localization/enUS.lua

    Base locale and fallback. Every user visible string in the addon lives here
    and is reached through ns.L["KEY"] -- never hard coded in a UI or data
    module.

    A missing key returns the key itself instead of nil, so a translation gap
    degrades into a visible-but-harmless label rather than a Lua error.
]]

local _, ns = ...

local L = {}

ns.L = setmetatable(L, {
    __index = function(_, key)
        -- Retail's UI debugger probes values for a ToDebugString member while
        -- it builds error descriptions. That is not a localization lookup;
        -- treating it as one produces a misleading warning in chat and can
        -- obscure the real UI error that caused the probe.
        if key == "ToDebugString" then
            return nil
        end

        ns.Debug:Warn("L10N", "missing string: %s", tostring(key))
        return key
    end,
})

local Localization = { packs = {}, effectiveLocale = "enUS" }
ns.Localization = Localization

function Localization:Register(locale, values)
    self.packs[locale] = values
end

function Localization:GetClientLocale()
    return GetLocale and GetLocale() or "enUS"
end

function Localization:GetEffectiveLocale()
    return self.effectiveLocale
end

-- Window ---------------------------------------------------------------------
L["ADDON_TITLE"] = "Shiny Hunter"
L["JOURNAL_TITLE"] = "Hunter's Bestiary"
L["PROGRESS_FORMAT"] = "%d / %d"
L["CATALOG_NUMBER_FORMAT"] = "#%03d"

-- Browser and detail panel ---------------------------------------------------
L["STATUS_COLLECTED"] = "Collected"
L["STATUS_SEEN"] = "Seen"
L["STATUS_MISSING"] = "Missing"
L["STATUS_PENDING"] = "Pending"
L["STATUS_IGNORED"] = "Ignored"

L["FILTER_SEARCH_PLACEHOLDER"] = "Search pets, families, zones..."
L["FILTER_ALL"] = "All"
L["FILTER_STATUS"] = "Status"
L["FILTER_FAMILY"] = "Family"
L["FILTER_EXPANSION"] = "Expansion"
L["FILTER_TRAIT"] = "Trait"
L["FILTER_ZONE"] = "Zone"
L["FILTER_FAVORITES"] = "Favourites"
L["FILTER_NO_RESULTS"] = "No pets found"
L["FILTER_NO_RESULTS_HINT"] = "Clear the search or change a filter"

L["TRAIT_EXOTIC"] = "Exotic"
L["TRAIT_RARE"] = "Rare"
L["TRAIT_ELITE"] = "Elite"
L["TRAIT_LEVEL"] = "Level %d-%d"

L["DETAIL_NO_SELECTION"] = "Select a pet from the list"
L["DETAIL_UNDISCOVERED"] = "UNDISCOVERED"
L["DETAIL_SCROLL_HINT"] = "Mouse wheel for more"
L["DETAIL_COORDINATE_HINT"] = "Select a point to start there"
L["DETAIL_POINT_ACTIVE"] = "ACTIVE"
L["DETAIL_WAYPOINT_TOOLTIP"] = "Automatically patrol every spawn area"
L["DETAIL_WAYPOINT_TOOLTIP_HINT"] = "The selected point starts the route; nearby samples are grouped and the hunt advances on arrival."
L["DETAIL_SOURCES"] = "Where to find it"
L["DETAIL_COORDS"] = "%.1f, %.1f"
L["DETAIL_NO_COORDS"] = "exact spawn points not verified"
L["DETAIL_ZONE_UNKNOWN"] = "Unknown zone"
L["DETAIL_LOCATION_UNKNOWN"] = "No known location"
L["DETAIL_NO_MODEL"] = "No model preview: no display id has been verified for this appearance yet."
L["MODEL_HINT"] = "Drag to rotate, scroll to zoom"
L["MINIMAP_TOOLTIP"] = "Click to open your collection. Drag to move this button."

-- Native navigation ---------------------------------------------------------
L["NAV_DEFAULT_TITLE"] = "Hunter destination"
L["NAV_HUNT_LABEL"] = "FIELD HUNT"
L["NAV_UNAVAILABLE"] = "A waypoint cannot be placed on this map."
L["NAV_NO_EXACT_LOCATIONS"] = "This appearance has no verified patrol points yet."
L["NAV_ROUTE_STEP"] = "Next: %s"
L["NAV_ROUTE_DESTINATION"] = "Destination: %s · open the world map for the travel route"
L["NAV_ROUTE_CALCULATING"] = "Calculating the next travel step..."
L["NAV_PATROL_PROGRESS"] = "Area %d/%d · automatic sweep"
L["NAV_PATROL_PROGRESS_DISTANCE"] = "Area %d/%d · %d yd · automatic sweep"
L["NAV_TARGET_FOUND"] = "Target sighted. Automatic patrol stopped."
L["MAP_SEARCH_AREA"] = "Possible spawn area"
L["MAP_SEARCH_COORDS"] = "Coordinates %.1f, %.1f"
L["MAP_SEARCH_HINT"] = "Click to track this exact point."
L["MAP_RARE_AUTOMATIC"] = "Rare tameable beast in this zone"
L["MAP_ROUTE_ADD_HINT"] = "Click to reveal its trail; other trails remain visible."
L["MAP_ROUTE_REMOVE_HINT"] = "Click to hide this trail."
L["MAP_RARE_POINTS"] = "%d known search points"
L["MAP_RARE_POINTS_ONE"] = "%d known search point"
L["MAP_RARE_TRACK_HINT"] = "Right-click to start or stop automatic tracking."

L["ALERT_PROGRESS_RECORDED"] = "HUNTER JOURNAL UPDATED"
L["ALERT_COMPLETION_CAPTURED"] = "Captured"
L["ALERT_COMPLETION_KILLED"] = "Defeated"

-- Hunt instrument -----------------------------------------------------------
L["HUNT_PANEL_TITLE"] = "FIELD TRACKING"
L["HUNT_READY_FORMAT"] = "%s · %d recorded traces"
L["HUNT_MAPS_FORMAT"] = "%d hunting grounds"
L["HUNT_NO_ROUTE"] = "No verified trail"
L["HUNT_ACTIVE_FORMAT"] = "Search area %d of %d · automatic sweep"
L["BUTTON_HUNT_START"] = "Track beast"
L["BUTTON_HUNT_STOP"] = "Stop tracking"
L["BUTTON_SHOW_COORDS"] = "Show exact points"
L["BUTTON_HIDE_COORDS"] = "Hide exact points"

-- Nameplate badges ------------------------------------------------------------
L["SKIN_NEW"] = "New sighting"
L["SKIN_COMMON"] = "Common"
L["SKIN_RARE"] = "Rare"
L["SKIN_EXOTIC"] = "Exotic"

-- Encounter alert -----------------------------------------------------------
L["ALERT_RARE_BEAST"] = "RARE BEAST SIGHTED"
L["ALERT_EXOTIC_BEAST"] = "EXOTIC BEAST SIGHTED"
L["ALERT_NOTABLE_BEAST"] = "NOTABLE BEAST SIGHTED"
L["ALERT_TRACKED_BEAST"] = "YOUR HUNT IS IN SIGHT"
L["ALERT_FAMILY_FORMAT"] = "%s · Hunter pet candidate"
L["ALERT_SCOPE_TITLE"] = "FIELD ALERTS"
L["ALERT_SCOPE_HINT"] = "Choose which encounters interrupt your hunt."
L["ALERT_SCOPE_CATALOG"] = "Ledger only · 604"
L["ALERT_SCOPE_ALL"] = "All rare & exotic"

L["TAB_COLLECTION"] = "Collection"
L["TAB_STABLE"] = "My stable"
L["TAB_SIGHTINGS"] = "Sightings"
L["TAB_TERRITORIES"] = "Territories"
L["TAB_RARE_CATALOG"] = "Rare ledger"
L["TAB_GUIDE"] = "Field guide"
L["TAB_OPTIONS"] = "Options"
L["GUIDE_TITLE"] = "Your first hunt"
L["GUIDE_INTRO"] = "Shiny Hunter records the tameable rares you discover, capture or defeat. Start from the ledger and let the field tools do the rest."
L["GUIDE_STEP_ONE_TITLE"] = "1. Choose a beast"
L["GUIDE_STEP_ONE_TEXT"] = "Open the Rare ledger, filter a region, and select a dossier. Grey entries are still unrecorded; colour means you have captured or defeated that exact rare."
L["GUIDE_STEP_TWO_TITLE"] = "2. Track the trail"
L["GUIDE_STEP_TWO_TEXT"] = "Use Track beast. The world map shows every known search area; the route advances automatically as you reach each area."
L["GUIDE_STEP_THREE_TITLE"] = "3. Record the encounter"
L["GUIDE_STEP_THREE_TEXT"] = "Taming, keeping an active pet, or defeating a named rare updates its dossier. Your stable is a separate snapshot and never limits journal progress."
L["GUIDE_AUTOMATIC_TITLE"] = "What happens automatically"
L["GUIDE_AUTOMATIC_TEXT"] = "Rare map pins, sighting alerts, sounds, stable reconciliation and territory seals work without RareScanner or any other addon."
L["OPTIONS_TITLE"] = "Journal options"
L["OPTIONS_LANGUAGE_TITLE"] = "Journal language"
L["OPTIONS_LANGUAGE_HINT"] = "Auto follows the game client. Changing it rebuilds the journal immediately; it does not change World of Warcraft's own language."
L["OPTIONS_LANGUAGE_AUTO"] = "Auto — game client (%s)"
L["OPTIONS_LANGUAGE_ACTIVE"] = "Active: %s"
L["LOCALE_ENUS"] = "English (US)"
L["LOCALE_ENGB"] = "English (UK)"
L["LOCALE_ESES"] = "Spanish"
L["LOCALE_ESMX"] = "Spanish (Latin America)"
L["LOCALE_DEDE"] = "German"
L["LOCALE_FRFR"] = "French"
L["LOCALE_ITIT"] = "Italian"
L["LOCALE_PTBR"] = "Portuguese (Brazil)"
L["RARE_CATALOG_TITLE"] = "Tameable rare-beast ledger"
L["RARE_CATALOG_SUMMARY"] = "%d shown · %d total"
L["RARE_CATALOG_TRACES"] = "%d exact traces"
L["RARE_CATALOG_ZONE_ONLY"] = "Zone known"
L["RARE_CATALOG_CAPTURED"] = "Captured"
L["RARE_CATALOG_KILLED"] = "Defeated"
L["RARE_CATALOG_CAPTURED_AND_KILLED"] = "Captured and defeated"
L["RARE_CATALOG_FAMILY_UNKNOWN"] = "Hunter pet"
L["RARE_CATALOG_MAP_FORMAT"] = "Map %d"
L["RARE_CATALOG_ALL_REGIONS"] = "All regions"
L["RARE_CATALOG_SELECT"] = "Select a rare beast to open its field dossier."
L["RARE_CATALOG_DETAIL_FORMAT"] = "Hunting ground: %s\nSpecialization: %s\nRecorded exact traces: %d"
L["RARE_CATALOG_GLOBAL_COMPLETED"] = "Global: %d / %d recorded"
L["RARE_CATALOG_REGION_COMPLETED"] = "In %s: %d / %d recorded"
L["REGION_PROGRESS_TITLE"] = "Territory trophies"
L["REGION_PROGRESS_SUBTITLE"] = "Capture or defeat every named tameable rare recorded in a continent to earn its field seal. Select a territory to open its collection."
L["REGION_COMPLETE"] = "Field seal earned"
L["REGION_IN_PROGRESS"] = "Hunt in progress"
L["REGION_TOAST_EYEBROW"] = "TERRITORY MASTERED"
L["REGION_TOAST_DETAIL"] = "%d named rares recorded"
L["STABLE_PANEL_HEADER"] = "Stable read on %s"
L["STABLE_PANEL_NEVER"] = "Your stable has not been read yet.\n\nVisit a stable master once with the stable window open and your pets will be listed here."
L["SIGHTINGS_EMPTY_USEFUL"] = "No encounters yet. Catalogued rare beasts will appear here with a direct link to their dossier."
L["SIGHTINGS_KNOWN_HEADER"] = "Catalogued encounters"
L["SIGHTINGS_OPEN_DOSSIER"] = "Open dossier"
L["BUTTON_RESET_VIEW"] = "Reset view"
L["DETAIL_DEV_SAMPLE"] = "Development sample, not verified data."

L["BUTTON_FAVORITE_ADD"] = "Add to favourites"
L["BUTTON_FAVORITE_REMOVE"] = "Remove favourite"
L["BUTTON_MARK_COLLECTED"] = "Mark as collected"
L["BUTTON_MARK_MISSING"] = "Mark as missing"
L["DETAIL_IN_STABLE"] = "In your stable"
L["DETAIL_SEEN_IN_WORLD"] = "You have met this one in the world"

-- Sighting log -----------------------------------------------------------------
L["SIGHTINGS_TITLE"] = "Shiny Hunter sightings"
L["SIGHTINGS_EMPTY"] = "Nothing logged yet. Target a tameable beast the database does not know and it will appear here."
L["SIGHTINGS_SUMMARY"] = "Met and not in the database: %d, of which rare: %d"
L["SIGHTINGS_RARE_MARK"] = "rare"
L["SIGHTINGS_HINT"] = "These came from your own client. Rare ones are prioritised; ordinary family skins also help complete the appearance catalogue."

-- Stable scanner -------------------------------------------------------------
L["STABLE_REPORT_TITLE"] = "Shiny Hunter stable report"
L["STABLE_REPORT_FRAME"] = "Stable window: %s"
L["STABLE_STATE_OPEN"] = "open"
L["STABLE_STATE_CLOSED"] = "closed"
L["STABLE_REPORT_NO_API"] = "C_StableInfo is not available on this client."
L["STABLE_REPORT_EMPTY"] = "The client returned no pets, and nothing has been saved for this character yet. Visit a stable master once with the stable window open."
L["STABLE_REPORT_SAVED"] = "No live read available. Showing the snapshot saved on %s:"
L["STABLE_REPORT_SUMMARY"] = "Pets read: %d. Recognised: %d. Display ids the database does not know: %d"
L["STABLE_REPORT_UNKNOWN_HINT"] = "Those display ids are verified values from your own client. They are what the database is missing."
L["STABLE_AUTO_MARKED"] = "Marked %d appearances as collected from your stable."
L["STABLE_AUTO_MARKED_ONE"] = "Marked one appearance as collected from your stable."

-- Slash commands -------------------------------------------------------------
L["CMD_HELP_HEADER"] = "Available commands:"
L["CMD_HELP_OPEN"] = "/shiny - open or close the main window"
L["CMD_HELP_DEBUG"] = "/shiny debug - toggle diagnostic output"
L["CMD_HELP_DUMP"] = "/shiny debug dump - print recent diagnostic lines"
L["CMD_HELP_VERSION"] = "/shiny version - show version information"
L["CMD_HELP_VALIDATE"] = "/shiny validate - check the pet database and run the self-tests"
L["CMD_HELP_STABLE"] = "/shiny stable - report what the client tells us about your stable"
L["CMD_HELP_SIGHTINGS"] = "/shiny sightings - list tameable beasts you met that are not in the database"
L["CMD_HELP_SHARE"] = "/shiny share - copy your field notes so they can reach the catalogue"
L["SHARE_TITLE"] = "Field notes"
L["SHARE_INTRO"] = "%d records your client gathered that the shipped catalogue does not carry. Nothing is sent anywhere: copy this and paste it wherever you like."
L["SHARE_HINT"] = "Already selected. Ctrl+C to copy, Escape to close."
L["SHARE_EMPTY"] = "Nothing to share yet. Walk past a beast the catalogue does not know and it will be recorded here."
L["CMD_HELP_RESET"] = "/shiny reset - erase stored data (asks for confirmation)"
L["CMD_HELP_HELP"] = "/shiny help - show this list"
L["CMD_UNKNOWN"] = "Unknown command: %s. Type /shiny help for the list."

-- Debug ----------------------------------------------------------------------
L["DEBUG_ON"] = "Debug output enabled."
L["DEBUG_OFF"] = "Debug output disabled."
L["DEBUG_DUMP_EMPTY"] = "No diagnostic lines recorded."
L["DEBUG_DUMP_HEADER"] = "Last %d diagnostic lines:"
L["DEBUG_DUMP_HEADER_ONE"] = "Last diagnostic line:"
L["ERROR_IN_CONTEXT"] = "An error occurred in %s. Please report it."

-- Version --------------------------------------------------------------------
L["VERSION_INFO"] = "Version %s. Client %s, interface %s."

-- Database -------------------------------------------------------------------
L["DB_NEWER_SCHEMA"] = "Your saved data was written by a newer version of Shiny Hunter. Nothing will be modified until you update the addon."
L["RESET_CONFIRM"] = "This erases every favourite and collection mark stored by Shiny Hunter. Type /shiny reset confirm to proceed."
L["RESET_DONE"] = "Stored data erased."

-- Validation -----------------------------------------------------------------
L["VALIDATE_TITLE"] = "Shiny Hunter Data Validation"
L["VALIDATE_LABEL_FAMILIES"] = "Families"
L["VALIDATE_LABEL_APPEARANCES"] = "Appearances"
L["VALIDATE_LABEL_CREATURES"] = "Creatures"
L["VALIDATE_LABEL_LOCATIONS"] = "Locations"
L["VALIDATE_LABEL_REQUIREMENTS"] = "Requirements"
L["VALIDATE_LABEL_ERRORS"] = "Errors"
L["VALIDATE_LABEL_WARNINGS"] = "Warnings"
L["VALIDATE_PROVENANCE"] = "Verified appearances: %d. Development samples: %d."
L["VALIDATE_ALL_GOOD"] = "No problems found."
L["VALIDATE_DETAIL_HINT"] = "Enable /shiny debug and run /shiny validate again for the detail of each entry."
L["TESTS_SUMMARY"] = "Self-tests — passed: %d, failed: %d"

-- Pet families ---------------------------------------------------------------
-- Names taken verbatim from the client's own CreatureFamily.db2.
L["FAMILY_WOLF"] = "Wolf"
L["FAMILY_CAT"] = "Cat"
L["FAMILY_SPIDER"] = "Spider"
L["FAMILY_BEAR"] = "Bear"
L["FAMILY_BOAR"] = "Boar"
L["FAMILY_CROCOLISK"] = "Crocolisk"
L["FAMILY_CARRION_BIRD"] = "Carrion Bird"
L["FAMILY_CRAB"] = "Crab"
L["FAMILY_GORILLA"] = "Gorilla"
L["FAMILY_RAPTOR"] = "Raptor"
L["FAMILY_TALLSTRIDER"] = "Tallstrider"
L["FAMILY_SCORPID"] = "Scorpid"
L["FAMILY_TURTLE"] = "Turtle"
L["FAMILY_BAT"] = "Bat"
L["FAMILY_HYENA"] = "Hyena"
L["FAMILY_BIRD_OF_PREY"] = "Bird of Prey"
L["FAMILY_WIND_SERPENT"] = "Wind Serpent"
L["FAMILY_DRAGONHAWK"] = "Dragonhawk"
L["FAMILY_RAVAGER"] = "Ravager"
L["FAMILY_WARP_STALKER"] = "Warp Stalker"
L["FAMILY_SPOREBAT"] = "Sporebat"
L["FAMILY_RAY"] = "Ray"
L["FAMILY_SERPENT"] = "Serpent"
L["FAMILY_MOTH"] = "Moth"
L["FAMILY_CHIMAERA"] = "Chimaera"
L["FAMILY_DEVILSAUR"] = "Devilsaur"
L["FAMILY_AQIRI"] = "Aqiri"
L["FAMILY_WORM"] = "Worm"
L["FAMILY_CLEFTHOOF"] = "Clefthoof"
L["FAMILY_WASP"] = "Wasp"
L["FAMILY_CORE_HOUND"] = "Core Hound"
L["FAMILY_SPIRIT_BEAST"] = "Spirit Beast"
L["FAMILY_FOX"] = "Fox"
L["FAMILY_MONKEY"] = "Monkey"
L["FAMILY_HOUND"] = "Hound"
L["FAMILY_BEETLE"] = "Beetle"
L["FAMILY_SHALE_BEAST"] = "Shale Beast"
L["FAMILY_HYDRA"] = "Hydra"
L["FAMILY_WATERFOWL"] = "Waterfowl"
L["FAMILY_WATER_STRIDER"] = "Water Strider"
L["FAMILY_RODENT"] = "Rodent"
L["FAMILY_STONE_HOUND"] = "Stone Hound"
L["FAMILY_GRUFFHORN"] = "Gruffhorn"
L["FAMILY_BASILISK"] = "Basilisk"
L["FAMILY_DIREHORN"] = "Direhorn"
L["FAMILY_RIVERBEAST"] = "Riverbeast"
L["FAMILY_STAG"] = "Stag"
L["FAMILY_MECHANICAL"] = "Mechanical"
L["FAMILY_SCALEHIDE"] = "Scalehide"
L["FAMILY_OXEN"] = "Oxen"
L["FAMILY_FEATHERMANE"] = "Feathermane"
L["FAMILY_LIZARD"] = "Lizard"
L["FAMILY_PTERRORDAX"] = "Pterrordax"
L["FAMILY_HOPPER"] = "Hopper"
L["FAMILY_CARAPID"] = "Carapid"
L["FAMILY_BLOOD_BEAST"] = "Blood Beast"
L["FAMILY_CAMEL"] = "Camel"
L["FAMILY_COURSER"] = "Courser"
L["FAMILY_MAMMOTH"] = "Mammoth"
L["FAMILY_LESSER_DRAGONKIN"] = "Lesser Dragonkin"
L["FAMILY_WHIPTAIL"] = "Whiptail"

-- Appearances ----------------------------------------------------------------
-- Proper names. They are intentionally not translated in other locales; see
-- Localization/esES.lua.
L["APPEARANCE_LOQUENAHAK"] = "Loque'nahak"
L["APPEARANCE_SKOLL"] = "Skoll"
L["APPEARANCE_GONDRIA"] = "Gondria"
L["APPEARANCE_ARCTURIS"] = "Arcturis"
L["APPEARANCE_HUMAR_THE_PRIDELORD"] = "Humar the Pridelord"
L["APPEARANCE_KING_KRUSH"] = "King Krush"
L["APPEARANCE_ANKHA"] = "Ankha"
L["APPEARANCE_BANTHALOS"] = "Ban'thalos"
L["APPEARANCE_BLOODGULLET"] = "Bloodgullet"
L["APPEARANCE_BULVINKEL"] = "Bulvinkel"
L["APPEARANCE_GHOSTCRAWLER"] = "Ghostcrawler"
L["APPEARANCE_KAROMA"] = "Karoma"
L["APPEARANCE_LIGHTNING_PAW"] = "Lightning Paw"
L["APPEARANCE_MAGRIA"] = "Magria"
L["APPEARANCE_MYONIX"] = "Myonix"
L["APPEARANCE_PASHYA"] = "Pashya"
L["APPEARANCE_AOTONA"] = "Aotona"

-- Specializations ------------------------------------------------------------
L["SPEC_FEROCITY"] = "Ferocity"
L["SPEC_TENACITY"] = "Tenacity"
L["SPEC_CUNNING"] = "Cunning"

-- Source types ---------------------------------------------------------------
L["SOURCE_WORLD"] = "World"
L["SOURCE_DUNGEON"] = "Dungeon"
L["SOURCE_RAID"] = "Raid"
L["SOURCE_EVENT"] = "Event"
L["SOURCE_DELVE"] = "Delve"

-- Requirements ---------------------------------------------------------------
L["REQ_BEAST_MASTERY"] = "Beast Mastery specialization required"

-- Expansions -----------------------------------------------------------------
L["EXPANSION_CLASSIC"] = "Classic"
L["EXPANSION_TBC"] = "The Burning Crusade"
L["EXPANSION_WOTLK"] = "Wrath of the Lich King"
L["EXPANSION_CATACLYSM"] = "Cataclysm"
L["EXPANSION_MOP"] = "Mists of Pandaria"
L["EXPANSION_WOD"] = "Warlords of Draenor"
L["EXPANSION_LEGION"] = "Legion"
L["EXPANSION_BFA"] = "Battle for Azeroth"
L["EXPANSION_SHADOWLANDS"] = "Shadowlands"
L["EXPANSION_DRAGONFLIGHT"] = "Dragonflight"
L["EXPANSION_TWW"] = "The War Within"
L["EXPANSION_MIDNIGHT"] = "Midnight"

-- Capture the immutable English base only after every key has been declared.
Localization.base = {}
for key, value in pairs(L) do Localization.base[key] = value end

function Localization:Apply(requested)
    requested = requested or "auto"
    local locale = requested == "auto" and self:GetClientLocale() or requested
    local pack = self.packs[locale]
    wipe(L)
    for key, value in pairs(self.base) do L[key] = value end
    if pack then
        for key, value in pairs(pack) do L[key] = value end
    elseif locale ~= "enUS" and locale ~= "enGB" then
        locale = "enUS"
    end
    self.effectiveLocale = locale
    if ns.Events then ns.Events:Send("LOCALE_CHANGED", locale) end
    return locale
end
L["SIGHTINGS_CANDIDATE_HEADER"] = "Rare beasts the catalogue is missing"
L["SIGHTINGS_CANDIDATE_STATUS"] = "Catalogue candidate"
L["SIGHTINGS_SURVEY_HEADER"] = "Ordinary skins surveyed"
L["SIGHTINGS_SURVEY_COUNT"] = "%d tameable beasts recorded"
L["SIGHTINGS_SURVEY_COUNT_ONE"] = "%d tameable beast recorded"
L["SIGHTINGS_SURVEY_NOTE"] = "A record of what lives where you walked. Not a task list: no catalogue holds every boar."
L["RARE_CATALOG_VARIANT"] = "variant %d of %d"
L["TRAVEL_STEP_PORTAL"] = "Take the portal to %s"
L["TRAVEL_STEP_BOAT"] = "Take the boat to %s"
L["TRAVEL_STEP_ZEPPELIN"] = "Take the zeppelin to %s"
L["TRAVEL_STEP_GENERIC"] = "Travel to %s"
L["TRAVEL_RECORD_DEPARTURE"] = "Departure noted: %s (%.1f, %.1f). Travel, then run the command again."
L["TRAVEL_RECORD_DONE"] = "Route recorded: %s to %s."
L["TRAVEL_RECORD_SAME_MAP"] = "You have not changed map yet. Travel first, then run it again."
L["TRAVEL_RECORD_NO_POSITION"] = "Your position is unavailable here."
L["TRAVEL_RECORD_CANCELLED"] = "Departure forgotten."
L["CMD_HELP_PORTAL"] = "/shiny portal - record a portal, boat or zeppelin by travelling it"
L["TRAVEL_STEP_SHIP"] = "Take the ship to %s"
L["TRAVEL_STEP_TRAM"] = "Take the tram to %s"
L["TRAVEL_STEP_FLIGHT"] = "Fly to %s"
