package locale import ( "encoding/json" "strings" ) type LocaleEntry struct { LanguageName string `json:"language_name"` LanguageLocal string `json:"language_local"` LanguageCode string `json:"language_code"` LanguageCode2 string `json:"language_code2"` LanguageCode3 string `json:"language_code3"` Regions []RegionEntry `json:"regions"` } type RegionEntry struct { Locale string `json:"locale"` CountryName string `json:"country_name"` CountryLocal string `json:"country_local"` CountryCode string `json:"country_code"` Flag string `json:"flag"` MajorRegionalVariant bool `json:"major_regional_variant"` Population int `json:"population"` } func LoadFromJSON(jsonData []byte) ([]LocaleEntry, error) { var locales []LocaleEntry if err := json.Unmarshal(jsonData, &locales); err != nil { return nil, err } return locales, nil } // CanonicalLanguageCode returns the selectable code used by mpv and the UI. // ISO 639-1 is preferred when present; languages without a two-letter code // fall back to their ISO 639-2/3 code instead of becoming unresolvable. func CanonicalLanguageCode(entry LocaleEntry) string { for _, code := range []string{entry.LanguageCode, entry.LanguageCode2, entry.LanguageCode3} { if code = strings.ToLower(strings.TrimSpace(code)); code != "" { return code } } return "" } func FindByLanguageCode(code string, locales []LocaleEntry) *LocaleEntry { code = strings.ToLower(strings.TrimSpace(code)) if code == "" { return nil } for i := range locales { if CanonicalLanguageCode(locales[i]) == code || strings.EqualFold(locales[i].LanguageCode2, code) || strings.EqualFold(locales[i].LanguageCode3, code) { return &locales[i] } } return nil } func FindByLocale(locale string, locales []LocaleEntry) (*LocaleEntry, *RegionEntry) { for i := range locales { for j := range locales[i].Regions { if locales[i].Regions[j].Locale == locale { return &locales[i], &locales[i].Regions[j] } } } return nil, nil } // FindAndMergeByLanguageCode finds all entries with matching language code // and returns a merged entry with all regions combined func FindAndMergeByLanguageCode(languageCode string, locales []LocaleEntry) *LocaleEntry { languageCode = strings.ToLower(strings.TrimSpace(languageCode)) if languageCode == "" { return nil } var mergedEntry *LocaleEntry var mergedRegions []RegionEntry for i := range locales { if CanonicalLanguageCode(locales[i]) == languageCode { // If first entry, use it as base if mergedEntry == nil { entryCopy := locales[i] mergedEntry = &entryCopy mergedRegions = append(mergedRegions, locales[i].Regions...) } else { // Append regions from subsequent entries mergedRegions = append(mergedRegions, locales[i].Regions...) } } } if mergedEntry == nil { return nil } // Update with merged regions mergedEntry.Regions = mergedRegions return mergedEntry }