src/i18n/z_language_data.erl

%% @doc Mandatory background read on language tags: [1].
%%
%%      Some quotes from [1]:
%%
%%          The golden rule when creating language tags is to keep the tag as short as
%%          possible. Avoid region, script or other subtags except where they add useful
%%          distinguishing information. For instance, use 'ja' for Japanese and not
%%          'ja-JP', unless there is a particular reason that you need to say that this is
%%          Japanese as spoken in Japan, rather than elsewhere.
%%
%%          The entries in the registry follow certain conventions with regard to upper
%%          and lower letter-casing. For example, language tags are lower case, alphabetic
%%          region subtags are upper case, and script tags begin with an initial capital.
%%          This is only a convention!
%%
%%      Note that we use lower case subtags in subtag identifiers and URLs.
%%
%%          Language+extlang combinations are provided to accommodate legacy language tag
%%          forms, however, there is a single language subtag available for every
%%          language+extlang combination. That language subtag should be used rather than
%%          the language+extlang combination, where possible. For example, use 'yue'
%%          rather than 'zh-yue' for Cantonese, and 'afb' rather than 'ar-afb' for Gulf
%%          Arabic, if you can.

%%      Language identifiers can have the following forms:
%%      - language;
%%      - language-extlang;
%%      - language-region;
%%      - language-script;
%%      It is discouraged to use language-script-region, but it is possible if
%%      required.
%%      For a list of language, region and script codes, see [2].
%%      [1] http://www.w3.org/International/articles/language-tags/
%%      [2] http://www.iana.org/assignments/language-subtag-registry/language-subtag-registry
-module(z_language_data).

-export([
        is_language/1,
        to_language_atom/1,
        fallback/1,
        codes_bin/0,
        codes_atom/0,

        languages_map_flat/0,
        languages_map_main/0,
        languages_list/0,

        make_mod/0,
        make_mod_reload/0
    ]).

-define(MODULE_MAP, 'z_language_data$map').

-spec is_language( z_language:language() ) -> boolean().
is_language( Lang ) when is_atom(Lang); is_binary(Lang) ->
    maps:is_key(Lang, languages_map_flat());
is_language( Lang ) when is_list(Lang) ->
    is_language(z_convert:to_binary(Lang)).

-spec to_language_atom( z_language:language() ) -> {ok, atom()} | {error, not_a_language}.
to_language_atom( Lang ) when is_atom(Lang); is_binary(Lang) ->
    case maps:find(Lang, languages_map_flat()) of
        {ok, #{ code_atom := Code }} -> {ok, Code};
        error ->
            Lower = z_string:to_lower(z_convert:to_binary(Lang)),
            case maps:find(Lower, languages_map_flat()) of
                {ok, #{ code_atom := Code }} -> {ok, Code};
                error -> {error, not_a_language}
            end
    end;
to_language_atom( Lang ) when is_list(Lang) ->
    is_language(z_convert:to_binary(Lang)).


-spec fallback(  z_language:language() ) -> list( z_language:language_code() ).
fallback(Code) when is_atom(Code); is_binary(Code) ->
    try
        Fallback = erlang:apply(?MODULE_MAP, fallback, []),
        maps:get(Code, Fallback, [])
    catch _:_ ->
        make_mod(),
        fallback(Code)
    end;
fallback(Code) when is_list(Code) ->
    fallback(z_convert:to_binary(Code)).

-spec languages_map_flat() -> #{ (z_language:language_code() | binary()) => map() }.
languages_map_flat() ->
    try erlang:apply(?MODULE_MAP, languages_map_flat, [])
    catch _:_ -> make_mod(), languages_map_flat()
    end.

languages_map_main() ->
    try erlang:apply(?MODULE_MAP, languages_map_main, [])
    catch _:_ -> make_mod(), languages_map_main()
    end.


-spec codes_bin() -> list( binary() ).
codes_bin() ->
    try erlang:apply(?MODULE_MAP, codes_bin, [])
    catch _:_ -> make_mod(), codes_bin()
    end.

-spec codes_atom() -> list( atom() ).
codes_atom() ->
    try erlang:apply(?MODULE_MAP, codes_atom, [])
    catch _:_ -> make_mod(), codes_atom()
    end.

%% Generate and memorize a quick lookup map for language data.
make_mod() ->
    jobs:run(zotonic_singular_job, fun make_mod_1/0).

make_mod_1() ->
    case code:is_loaded(?MODULE_MAP) of
        false -> make_mod_reload();
        {file, _} -> ok
    end.

make_mod_reload() ->
    Ls = [ K || {K, _} <- languages_list() ],
    LsA = [ binary_to_atom(K,utf8) || K <- Ls ],
    Fallback = fetch_fallbacks( languages_list() ),
    Bin = compile(?MODULE_MAP, Ls, LsA, Fallback),
    code:purge(?MODULE_MAP),
    Filename = z_convert:to_list(?MODULE_MAP) ++ ".erl",
    code:load_binary(?MODULE_MAP, Filename, Bin).

fetch_fallbacks(List) ->
    fetch_fallback(List, [], #{}).

fetch_fallback([], _Path, Acc) ->
    Acc;
fetch_fallback([ {CodeBin, Props} | List ], Path0, Acc) ->
    Path = case proplists:get_value(fallback, Props) of
        undefined -> Path0;
        Fallback -> [ z_convert:to_atom(Fallback) | Path0 ]
    end,
    CodeAtom = z_convert:to_atom(CodeBin),
    Acc1 = Acc#{
        CodeBin => Path,
        CodeAtom => Path
    },
    Sub = proplists:get_value(sublanguages, Props, []),
    Acc2 = fetch_fallback(Sub, [ CodeAtom | Path ], Acc1),
    Acc3 = lists:foldl(
        fun(Alias, AliasAcc) ->
            AAtom = binary_to_atom(Alias, utf8),
            AliasAcc#{
                AAtom => Path,
                Alias => Path
            }
        end,
        Acc2,
        proplists:get_value(alias, Props, [])),
    fetch_fallback(List, Path0, Acc3).

as_map_flat(Fallback) ->
    as_map_flat(languages_list(), Fallback, #{}).

as_map_flat(List, Fallback, Map) ->
    lists:foldl(
        fun({Code, Props}, Acc) ->
            CodeAtom = binary_to_atom(Code, utf8),
            MapProps = as_map_flat_props(CodeAtom, Props, Fallback),
            Acc1 = Acc#{
                CodeAtom => MapProps,
                Code => MapProps
            },
            Acc2 = lists:foldl(
                fun(Alias, AliasAcc) ->
                    AAtom = binary_to_atom(Alias, utf8),
                    AliasAcc#{
                        AAtom => MapProps,
                        Alias => MapProps
                    }
                end,
                Acc1,
                proplists:get_value(alias, Props, [])),
            as_map_flat(proplists:get_value(sublanguages, Props, []), Fallback, Acc2)
        end,
        Map,
        List).

as_map_flat_props(CodeAtom, Props, Fallback) ->
    M = maps:from_list(Props),
    M#{
        code_atom => CodeAtom,
        code_bin => atom_to_binary(CodeAtom, utf8),
        language_atom => binary_to_atom( maps:get(language, M), utf8 ),
        sublanguages => as_atom_map(maps:get(sublanguages, M, []), Fallback, #{}),
        fallback => maps:get(CodeAtom, Fallback),
        sort_key => z_string:to_lower( proplists:get_value(name_en, Props) )
    }.

as_atom_map(Fallback) ->
    as_atom_map(languages_list(), Fallback, #{}).

as_atom_map(List, Fallback, Map) ->
    lists:foldl(
        fun({Code, Props}, Acc) ->
            CodeAtom = binary_to_atom(Code, utf8),
            MapProps = as_atom_map_props(CodeAtom, Props, Fallback),
            Acc#{
                CodeAtom => MapProps
            }
        end,
        Map,
        List).

as_atom_map_props(CodeAtom, Props, Fallback) ->
    M = maps:from_list(Props),
    M#{
        language_atom => binary_to_atom( maps:get(language, M), utf8 ),
        sublanguages => as_atom_map(maps:get(sublanguages, M, []), Fallback, #{}),
        fallback => maps:get(CodeAtom, Fallback),
        sort_key => z_string:to_lower( proplists:get_value(name_en, Props) )
    }.

-spec compile(atom(), list(), list(), map()) -> binary().
compile(Module, Ls, LsA, Fallback) ->
    {ok, Module, Bin} = compile:forms(forms(Module, Ls, LsA, Fallback),
                                      [verbose, report_errors]),
    Bin.

-spec forms(atom(), list(), list(), map()) -> [erl_syntax:syntaxTree()].
forms(Module, Ls, LsA, Fallback) ->
    [ erl_syntax:revert(X) || X <- term_to_abstract(Module, Ls, LsA, Fallback)].

-spec term_to_abstract(atom(), list(), list(), map()) -> [erl_syntax:syntaxTree()].
term_to_abstract(Module, Ls, LsA, Fallback) ->
[
    % -module(Module).
    erl_syntax:attribute(erl_syntax:atom(module), [erl_syntax:atom(Module)]),

    % -export([ ... ]).
    erl_syntax:attribute(
        erl_syntax:atom(export),
        [
            erl_syntax:list([
                erl_syntax:arity_qualifier(erl_syntax:atom(languages_map_flat), erl_syntax:integer(0)),
                erl_syntax:arity_qualifier(erl_syntax:atom(languages_map_main), erl_syntax:integer(0)),
                erl_syntax:arity_qualifier(erl_syntax:atom(fallback), erl_syntax:integer(0)),
                erl_syntax:arity_qualifier(erl_syntax:atom(codes_bin), erl_syntax:integer(0)),
                erl_syntax:arity_qualifier(erl_syntax:atom(codes_atom), erl_syntax:integer(0))
            ])
        ]),

    % Functions
    erl_syntax:function(
        erl_syntax:atom(languages_map_flat),
        [ erl_syntax:clause([], none, [ erl_syntax:abstract( as_map_flat(Fallback) )]) ]),
    erl_syntax:function(
        erl_syntax:atom(languages_map_main),
        [ erl_syntax:clause([], none, [erl_syntax:abstract( as_atom_map(Fallback) )]) ]),
    erl_syntax:function(
        erl_syntax:atom(fallback),
        [ erl_syntax:clause([], none, [erl_syntax:abstract(Fallback)]) ]),
    erl_syntax:function(
        erl_syntax:atom(codes_bin),
        [ erl_syntax:clause([], none, [erl_syntax:abstract(Ls)]) ]),
    erl_syntax:function(
        erl_syntax:atom(codes_atom),
        [ erl_syntax:clause([], none, [erl_syntax:abstract(LsA)]) ])
].


%% ================================================================================================================
%% ================================================================================================================
%% ================================================================================================================

-spec languages_list() -> list( {binary(), proplists:proplist()} ).
languages_list() -> [
    {<<"aa">>, [
        {language, <<"aa">>},
        {name, <<"Qafaraf"/utf8>>},
        {name_en, <<"Afar"/utf8>>}
    ]},
    {<<"ab">>, [
        {language, <<"ab">>},
        {script, <<"Cyrl">>},
        {region, <<"GE">>},
        {name, <<"Аҧсуа бызшәа"/utf8>>},
        {name_en, <<"Abkhazian"/utf8>>}
    ]},
    {<<"af">>, [
        {language, <<"af">>},
        {name, <<"Afrikaans"/utf8>>},
        {name_en, <<"Afrikaans"/utf8>>}
    ]},
    {<<"am">>, [
        {language, <<"am">>},
        {script, <<"Ethi">>},
        {region, <<"ET">>},
        {name, <<"አማርኛ"/utf8>>},
        {name_en, <<"Amharic"/utf8>>}
    ]},
    {<<"ar">>, [
        {type, <<"macro_language">>},
        {language, <<"ar">>},
        {direction, <<"RTL">>},
        {script, <<"Arab">>},
        {name, <<"العربية"/utf8>>},
        {name_en, <<"Arabic"/utf8>>},
        {sublanguages, [
            {<<"arb">>, [
                {language, <<"ar">>},
                {direction, <<"RTL">>},
                {script, <<"Arab">>},
                {name, <<"اللغة العربية الفصحى"/utf8>>},
                {name_en, <<"Standard Arabic"/utf8>>}
            ]},
            {<<"afb">>, [
                {language, <<"ar">>},
                {direction, <<"RTL">>},
                {script, <<"Arab">>},
                {name, <<"العربية - الخليج"/utf8>>},
                {name_en, <<"Arabic - Gulf"/utf8>>}
            ]},
            {<<"ajp">>, [
                {language, <<"ar">>},
                {direction, <<"RTL">>},
                {script, <<"Arab">>},
                {name, <<"العربية - جنوب بلاد الشام"/utf8>>},
                {name_en, <<"Arabic - South Levant"/utf8>>}
            ]},
            {<<"apc">>, [
                {language, <<"ar">>},
                {direction, <<"RTL">>},
                {script, <<"Arab">>},
                {name, <<"العربية - شمال بلاد الشام"/utf8>>},
                {name_en, <<"Arabic - North Levant"/utf8>>}
            ]},
            {<<"apd">>, [
                {language, <<"ar">>},
                {direction, <<"RTL">>},
                {script, <<"Arab">>},
                {name, <<"العربية - السودان"/utf8>>},
                {name_en, <<"Arabic - Sudan"/utf8>>}
            ]},
            {<<"ar-ae">>, [
                {language, <<"ar">>},
                {direction, <<"RTL">>},
                {region, <<"AE">>},
                {script, <<"Arab">>},
                {name, <<"العربية - الإمارات العربية المتحدة."/utf8>>},
                {name_en, <<"Arabic - U.A.E."/utf8>>}
            ]},
            {<<"ar-bh">>, [
                {language, <<"ar">>},
                {direction, <<"RTL">>},
                {region, <<"BH">>},
                {script, <<"Arab">>},
                {name, <<"العربية - البحرين"/utf8>>},
                {name_en, <<"Arabic - Bahrain"/utf8>>}
            ]},
            {<<"aao">>, [
                {language, <<"ar">>},
                {direction, <<"RTL">>},
                {region, <<"DZ">>},
                {script, <<"Arab">>},
                {name, <<"العربية الصحراء الجزائرية"/utf8>>},
                {name_en, <<"Arabic - Algerian Sahara"/utf8>>}
            ]},
            {<<"ary">>, [
                {language, <<"ar">>},
                {direction, <<"RTL">>},
                {region, <<"DZ">>},
                {script, <<"Arab">>},
                {name, <<"العربية - المغرب"/utf8>>},
                {name_en, <<"Arabic - Marocco"/utf8>>}
            ]},
            {<<"arz">>, [
                {language, <<"ar">>},
                {direction, <<"RTL">>},
                {region, <<"EG">>},
                {script, <<"Arab">>},
                {name, <<"مصر"/utf8>>},
                {name_en, <<"Arabic - Egypt"/utf8>>}
            ]},
            {<<"ar-iq">>, [
                {language, <<"ar">>},
                {direction, <<"RTL">>},
                {region, <<"IQ">>},
                {script, <<"Arab">>},
                {name, <<"العربية - مصر"/utf8>>},
                {name_en, <<"Arabic - Iraq"/utf8>>}
            ]},
            {<<"ar-jo">>, [
                {language, <<"ar">>},
                {direction, <<"RTL">>},
                {region, <<"JO">>},
                {script, <<"Arab">>},
                {name, <<"العربية - الأردن"/utf8>>},
                {name_en, <<"Arabic - Jordan"/utf8>>}
            ]},
            {<<"ar-kw">>, [
                {language, <<"ar">>},
                {direction, <<"RTL">>},
                {region, <<"KW">>},
                {script, <<"Arab">>},
                {name, <<"العربية - الكويت"/utf8>>},
                {name_en, <<"Arabic - Kuwait"/utf8>>}
            ]},
            {<<"ar-lb">>, [
                {language, <<"ar">>},
                {direction, <<"RTL">>},
                {region, <<"LB">>},
                {script, <<"Arab">>},
                {name, <<"العربية - لبنان"/utf8>>},
                {name_en, <<"Arabic - Lebanon"/utf8>>}
            ]},
            {<<"ayl">>, [
                {language, <<"ar">>},
                {direction, <<"RTL">>},
                {region, <<"LY">>},
                {script, <<"Arab">>},
                {name, <<"العربية - ليبيا"/utf8>>},
                {name_en, <<"Arabic - Libya"/utf8>>}
            ]},
            {<<"ar-ma">>, [
                {language, <<"ar">>},
                {direction, <<"RTL">>},
                {region, <<"MA">>},
                {script, <<"Arab">>},
                {name, <<"العربية - المغرب"/utf8>>},
                {name_en, <<"Arabic - Morocco"/utf8>>}
            ]},
            {<<"acx">>, [
                {language, <<"ar">>},
                {direction, <<"RTL">>},
                {region, <<"OM">>},
                {script, <<"Arab">>},
                {name, <<"العربية - عمان"/utf8>>},
                {name_en, <<"Arabic - Oman"/utf8>>}
            ]},
            {<<"ar-qa">>, [
                {language, <<"ar">>},
                {direction, <<"RTL">>},
                {region, <<"QA">>},
                {script, <<"Arab">>},
                {name, <<"العربية - قطر"/utf8>>},
                {name_en, <<"Arabic - Qatar"/utf8>>}
            ]},
            {<<"ar-sa">>, [
                {language, <<"ar">>},
                {direction, <<"RTL">>},
                {region, <<"SA">>},
                {script, <<"Arab">>},
                {name, <<"العربية - المملكة العربية السعودية"/utf8>>},
                {name_en, <<"Arabic - Saudi Arabia"/utf8>>}
            ]},
            {<<"ar-sy">>, [
                {language, <<"ar">>},
                {direction, <<"RTL">>},
                {region, <<"SY">>},
                {script, <<"Arab">>},
                {name, <<"العربية - سوريا"/utf8>>},
                {name_en, <<"Arabic - Syria"/utf8>>}
            ]},
            {<<"aeb">>, [
                {language, <<"ar">>},
                {direction, <<"RTL">>},
                {region, <<"TN">>},
                {script, <<"Arab">>},
                {name, <<"العربية - تونس"/utf8>>},
                {name_en, <<"Arabic - Tunisia"/utf8>>}
            ]},
            {<<"ar-ye">>, [
                {language, <<"ar">>},
                {direction, <<"RTL">>},
                {region, <<"YE">>},
                {script, <<"Arab">>},
                {name, <<"العربية - اليمن"/utf8>>},
                {name_en, <<"Arabic - Yemen"/utf8>>}
            ]}
        ]}
    ]},
    {<<"as">>, [
        {language, <<"as">>},
        {script, <<"Beng">>},
        {name, <<"অসমীয়া"/utf8>>},
        {name_en, <<"Assamese"/utf8>>}
    ]},
    {<<"ay">>, [
        {language, <<"ay">>},
        {name, <<"Aymar aru"/utf8>>},
        {name_en, <<"Aymara"/utf8>>}
    ]},
    {<<"az">>, [
        {type, <<"macrolanguage">>},
        {language, <<"az">>},
        {name, <<"Azərbaycan dili"/utf8>>},
        {name_en, <<"Azerbaijani"/utf8>>}
    ]},
    {<<"ba">>, [
        {language, <<"ba">>},
        {script, <<"Cyrl">>},
        {region, <<"RU">>},
        {name, <<"башҡорт теле"/utf8>>},
        {name_en, <<"Bashkir"/utf8>>}
    ]},
    {<<"be">>, [
        {language, <<"be">>},
        {script, <<"Cyrl">>},
        {region, <<"BY">>},
        {name, <<"беларуская"/utf8>>},
        {name_en, <<"Byelorussian"/utf8>>}
    ]},
    {<<"bg">>, [
        {language, <<"bg">>},
        {script, <<"Cyrl">>},
        {region, <<"BG">>},
        {name, <<"български"/utf8>>},
        {name_en, <<"Bulgarian"/utf8>>}
    ]},
    %% Omitting "bh", which is "Bihari languages", a collection
    {<<"bi">>, [
        {language, <<"bi">>},
        {region, <<"VU">>},
        {name, <<"Bislama"/utf8>>},
        {name_en, <<"Bislama"/utf8>>}
    ]},
    {<<"bn">>, [
        {language, <<"bn">>},
        {script, <<"Beng">>},
        {name, <<"বাংলা"/utf8>>},
        {name_en, <<"Bengali"/utf8>>}
    ]},
    {<<"bo">>, [
        {language, <<"bo">>},
        {script, <<"Tibt">>},
        {name, <<"བོད་སྐད"/utf8>>},
        {name_en, <<"Tibetan"/utf8>>}
    ]},
    {<<"br">>, [
        {language, <<"br">>},
        {name, <<"Brezhoneg"/utf8>>},
        {name_en, <<"Breton"/utf8>>}
    ]},
    {<<"bs">>, [
        {language, <<"bs">>},
        {region, <<"BA">>},
        {name, <<"Bosanski"/utf8>>},
        {name_en, <<"Bosnian"/utf8>>}
    ]},
    {<<"ca">>, [
        {language, <<"ca">>},
        {region, <<"AD">>},
        {name, <<"Català"/utf8>>},
        {name_en, <<"Catalan"/utf8>>}
    ]},
    {<<"ce">>, [
        {language, <<"ce">>},
        {script, <<"Cyrl">>},
        {region, <<"RU">>},
        {name, <<"нохчийн"/utf8>>},
        {name_en, <<"Chechen"/utf8>>}
    ]},
    {<<"ch">>, [
        {language, <<"ch">>},
        {region, <<"GU">>},
        {name, <<"Finu' Chamoru"/utf8>>},
        {name_en, <<"Chamorro"/utf8>>}
    ]},
    {<<"co">>, [
        {language, <<"co">>},
        {name, <<"Corsu"/utf8>>},
        {name_en, <<"Corsican"/utf8>>}
    ]},
    {<<"cs">>, [
        {language, <<"cs">>},
        {region, <<"CZ">>},
        {name, <<"Čeština"/utf8>>},
        {name_en, <<"Czech"/utf8>>}
    ]},
    %% Omitting Church Slavic
    {<<"cv">>, [
        {language, <<"cv">>},
        {region, <<"RU">>},
        {script, <<"Cyrl">>},
        {name, <<"Чӑвашла"/utf8>>},
        {name_en, <<"Chuvash"/utf8>>}
    ]},
    {<<"cy">>, [
        {language, <<"cy">>},
        {region, <<"GB">>},
        {name, <<"Cymraeg"/utf8>>},
        {name_en, <<"Welsh"/utf8>>}
    ]},
    {<<"de">>, [
        {language, <<"de">>},
        {name, <<"Deutsch"/utf8>>},
        {name_en, <<"German"/utf8>>},
        {sublanguages, [
            {<<"de-at">>, [
                {language, <<"de">>},
                {region, <<"AT">>},
                {name, <<"Deutsch - Österreich"/utf8>>},
                {name_en, <<"German - Austria"/utf8>>}
            ]},
            {<<"de-ch">>, [
                {language, <<"de">>},
                {region, <<"CH">>},
                {name, <<"Deutsch - Schweiz"/utf8>>},
                {name_en, <<"German - Switzerland"/utf8>>}
            ]},
            {<<"de-de">>, [
                {language, <<"de">>},
                {region, <<"DE">>},
                {name, <<"Deutsch - Deutschland"/utf8>>},
                {name_en, <<"German - Germany"/utf8>>}
            ]},
            {<<"de-li">>, [
                {language, <<"de">>},
                {region, <<"LI">>},
                {name, <<"Deutsch - Liechtenstein"/utf8>>},
                {name_en, <<"German - Liechtenstein"/utf8>>}
            ]},
            {<<"de-lu">>, [
                {language, <<"de">>},
                {region, <<"LU">>},
                {name, <<"Deutsch - Luxemburg"/utf8>>},
                {name_en, <<"German - Luxembourg"/utf8>>}
            ]}
        ]}
    ]},
    {<<"da">>, [
        {language, <<"da">>},
        {name, <<"Dansk"/utf8>>},
        {name_en, <<"Danish"/utf8>>}
    ]},
    {<<"dz">>, [
        {language, <<"dz">>},
        {script, <<"Tibt">>},
        {region, <<"BT">>},
        {name, <<"རྫོང་ཁ་"/utf8>>},
        {name_en, <<"Dzongkha"/utf8>>}
    ]},
    {<<"el">>, [
        {language, <<"el">>},
        {script, <<"Grek">>},
        {name, <<"Ελληνικά"/utf8>>},
        {name_en, <<"Greek"/utf8>>}
    ]},
    {<<"en">>, [
        {language, <<"en">>},
        {name, <<"English"/utf8>>},
        {name_en, <<"English"/utf8>>},
        {sublanguages, [
            {<<"en-au">>, [
                {language, <<"en">>},
                {region, <<"AU">>},
                {name, <<"English - Australia"/utf8>>},
                {name_en, <<"English - Australia"/utf8>>}
            ]},
            {<<"en-bz">>, [
                {language, <<"en">>},
                {region, <<"BZ">>},
                {name, <<"English - Belize"/utf8>>},
                {name_en, <<"English - Belize"/utf8>>}
            ]},
            {<<"en-ca">>, [
                {language, <<"en">>},
                {region, <<"CA">>},
                {name, <<"English - Canada"/utf8>>},
                {name_en, <<"English - Canada"/utf8>>}
            ]},
            {<<"en-cb">>, [
                {language, <<"en">>},
                {region, <<"CB">>},
                {name, <<"English - Caribbean"/utf8>>},
                {name_en, <<"English - Caribbean"/utf8>>}
            ]},
            {<<"en-gb">>, [
                {language, <<"en">>},
                {region, <<"GB">>},
                {name, <<"English - United Kingdom"/utf8>>},
                {name_en, <<"English - United Kingdom"/utf8>>}
            ]},
            {<<"en-ie">>, [
                {language, <<"en">>},
                {region, <<"IE">>},
                {name, <<"English - Ireland"/utf8>>},
                {name_en, <<"English - Ireland"/utf8>>}
            ]},
            {<<"en-jm">>, [
                {language, <<"en">>},
                {region, <<"JM">>},
                {name, <<"English - Jamaica"/utf8>>},
                {name_en, <<"English - Jamaica"/utf8>>}
            ]},
            {<<"en-nz">>, [
                {language, <<"en">>},
                {region, <<"NZ">>},
                {name, <<"English - New Zealand"/utf8>>},
                {name_en, <<"English - New Zealand"/utf8>>}
            ]},
            {<<"en-ph">>, [
                {language, <<"en">>},
                {region, <<"PH">>},
                {name, <<"English - Republic of the Philippines"/utf8>>},
                {name_en, <<"English - Republic of the Philippines"/utf8>>}
            ]},
            {<<"en-tt">>, [
                {language, <<"en">>},
                {region, <<"TT">>},
                {name, <<"English - Trinidad and Tobago"/utf8>>},
                {name_en, <<"English - Trinidad and Tobago"/utf8>>}
            ]},
            {<<"en-us">>, [
                {language, <<"en">>},
                {region, <<"US">>},
                {name, <<"English - United States"/utf8>>},
                {name_en, <<"English - United States"/utf8>>}
            ]},
            {<<"en-za">>, [
                {language, <<"en">>},
                {region, <<"ZA">>},
                {name, <<"English - South Africa"/utf8>>},
                {name_en, <<"English - South Africa"/utf8>>}
            ]},
            {<<"en-zw">>, [
                {language, <<"en">>},
                {region, <<"ZW">>},
                {name, <<"English - Zimbabwe"/utf8>>},
                {name_en, <<"English - Zimbabwe"/utf8>>}
            ]}
        ]}
    ]},
    {<<"eo">>, [
        {language, <<"eo">>},
        {name, <<"Esperanto"/utf8>>},
        {name_en, <<"Esperanto"/utf8>>}
    ]},
    {<<"es">>, [
        {language, <<"es">>},
        {name, <<"Español"/utf8>>},
        {name_en, <<"Spanish"/utf8>>},
        {sublanguages, [
            {<<"es-419">>, [
                {language, <<"es">>},
                {region, <<"419">>},
                {name, <<"Español latinoamericano"/utf8>>},
                {name_en, <<"Spanish - Latin America and the Caribbean"/utf8>>}
            ]},
            {<<"es-ar">>, [
                {language, <<"es">>},
                {region, <<"AR">>},
                {name, <<"Español - Argentina"/utf8>>},
                {name_en, <<"Spanish - Argentina"/utf8>>}
            ]},
            {<<"es-bo">>, [
                {language, <<"es">>},
                {region, <<"BO">>},
                {name, <<"Español - Bolivia"/utf8>>},
                {name_en, <<"Spanish - Bolivia"/utf8>>}
            ]},
            {<<"es-cl">>, [
                {language, <<"es">>},
                {region, <<"CL">>},
                {name, <<"Español - Chile"/utf8>>},
                {name_en, <<"Spanish - Chile"/utf8>>}
            ]},
            {<<"es-co">>, [
                {language, <<"es">>},
                {region, <<"CO">>},
                {name, <<"Español - Colombia"/utf8>>},
                {name_en, <<"Spanish - Colombia"/utf8>>}
            ]},
            {<<"es-cr">>, [
                {language, <<"es">>},
                {region, <<"CR">>},
                {name, <<"Español - Costa Rica"/utf8>>},
                {name_en, <<"Spanish - Costa Rica"/utf8>>}
            ]},
            {<<"es-do">>, [
                {language, <<"es">>},
                {region, <<"DO">>},
                {name, <<"Español - República Dominicana"/utf8>>},
                {name_en, <<"Spanish - Dominican Republic"/utf8>>}
            ]},
            {<<"es-ec">>, [
                {language, <<"es">>},
                {region, <<"EC">>},
                {name, <<"Español - Ecuador"/utf8>>},
                {name_en, <<"Spanish - Ecuador"/utf8>>}
            ]},
            {<<"es-es">>, [
                {language, <<"es">>},
                {region, <<"ES">>},
                {name, <<"Español - España"/utf8>>},
                {name_en, <<"Spanish - Spain"/utf8>>}
            ]},
            {<<"es-gt">>, [
                {language, <<"es">>},
                {region, <<"GT">>},
                {name, <<"Español - Guatemala"/utf8>>},
                {name_en, <<"Spanish - Guatemala"/utf8>>}
            ]},
            {<<"es-hn">>, [
                {language, <<"es">>},
                {region, <<"HN">>},
                {name, <<"Español - Honduras"/utf8>>},
                {name_en, <<"Spanish - Honduras"/utf8>>}
            ]},
            {<<"es-mx">>, [
                {language, <<"es">>},
                {region, <<"MX">>},
                {name, <<"Español - México"/utf8>>},
                {name_en, <<"Spanish - Mexico"/utf8>>}
            ]},
            {<<"es-ni">>, [
                {language, <<"es">>},
                {region, <<"NI">>},
                {name, <<"Español - Nicaragua"/utf8>>},
                {name_en, <<"Spanish - Nicaragua"/utf8>>}
            ]},
            {<<"es-pa">>, [
                {language, <<"es">>},
                {region, <<"PA">>},
                {name, <<"Español - Panamá"/utf8>>},
                {name_en, <<"Spanish - Panama"/utf8>>}
            ]},
            {<<"es-pe">>, [
                {language, <<"es">>},
                {region, <<"PE">>},
                {name, <<"Español - Perú"/utf8>>},
                {name_en, <<"Spanish - Peru"/utf8>>}
            ]},
            {<<"es-pr">>, [
                {language, <<"es">>},
                {region, <<"PR">>},
                {name, <<"Español - Puerto Rico"/utf8>>},
                {name_en, <<"Spanish - Puerto Rico"/utf8>>}
            ]},
            {<<"es-py">>, [
                {language, <<"es">>},
                {region, <<"PY">>},
                {name, <<"Español - Paraguay"/utf8>>},
                {name_en, <<"Spanish - Paraguay"/utf8>>}
            ]},
            {<<"es-sv">>, [
                {language, <<"es">>},
                {region, <<"SV">>},
                {name, <<"Español - El Salvador"/utf8>>},
                {name_en, <<"Spanish - El Salvador"/utf8>>}
            ]},
            {<<"es-uy">>, [
                {language, <<"es">>},
                {region, <<"UY">>},
                {name, <<"Español - Uruguay"/utf8>>},
                {name_en, <<"Spanish - Uruguay"/utf8>>}
            ]},
            {<<"es-ve">>, [
                {language, <<"es">>},
                {region, <<"VE">>},
                {name, <<"Español - Venezuela"/utf8>>},
                {name_en, <<"Spanish - Venezuela"/utf8>>}
            ]}
        ]}
    ]},
    {<<"et">>, [
        {language, <<"et">>},
        {region, <<"EE">>},
        {name, <<"Eesti"/utf8>>},
        {name_en, <<"Estonian"/utf8>>}
    ]},
    {<<"eu">>, [
        {language, <<"eu">>},
        {region, <<"ES">>},
        {name, <<"Euskara"/utf8>>},
        {name_en, <<"Basque"/utf8>>}
    ]},
    {<<"fa">>, [
        {language, <<"fa">>},
        {direction, <<"RTL">>},
        {script, <<"Arab">>},
        {name, <<"فارسی"/utf8>>},
        {name_en, <<"Persian"/utf8>>}
    ]},
    {<<"fi">>, [
        {language, <<"fi">>},
        {name, <<"Suomi"/utf8>>},
        {name_en, <<"Finnish"/utf8>>}
    ]},
    {<<"fj">>, [
        {language, <<"fj">>},
        {region, <<"FJ">>},
        {name, <<"Na Vosa Vakaviti"/utf8>>},
        {name_en, <<"Fijian"/utf8>>}
    ]},
    {<<"fr">>, [
        {language, <<"fr">>},
        {name, <<"Français"/utf8>>},
        {name_en, <<"French"/utf8>>},
        {sublanguages, [
            {<<"fr-be">>, [
                {language, <<"fr">>},
                {region, <<"BE">>},
                {name, <<"Français - Belgique"/utf8>>},
                {name_en, <<"French - Belgium"/utf8>>}
            ]},
            {<<"fr-ca">>, [
                {language, <<"fr">>},
                {region, <<"CA">>},
                {name, <<"Français - Canada"/utf8>>},
                {name_en, <<"French - Canada"/utf8>>}
            ]},
            {<<"fr-ch">>, [
                {language, <<"fr">>},
                {region, <<"CH">>},
                {name, <<"Français - Suisse"/utf8>>},
                {name_en, <<"French - Switzerland"/utf8>>}
            ]},
            {<<"fr-fr">>, [
                {language, <<"fr">>},
                {region, <<"FR">>},
                {name, <<"Français - France"/utf8>>},
                {name_en, <<"French - France"/utf8>>}
            ]},
            {<<"fr-lu">>, [
                {language, <<"fr">>},
                {region, <<"LU">>},
                {name, <<"Français - Luxembourg"/utf8>>},
                {name_en, <<"French - Luxembourg"/utf8>>}
            ]},
            {<<"fr-mc">>, [
                {language, <<"fr">>},
                {region, <<"MC">>},
                {name, <<"Français - Monaco"/utf8>>},
                {name_en, <<"French - Monaco"/utf8>>}
            ]}
        ]}
    ]},
    {<<"fo">>, [
        {language, <<"fo">>},
        {region, <<"FO">>},
        {name, <<"Føroyskt"/utf8>>},
        {name_en, <<"Faroese"/utf8>>}
    ]},
    {<<"fy">>, [
        {language, <<"fy">>},
        {region, <<"NL">>},
        {name, <<"West-Frysk"/utf8>>},
        {name_en, <<"Frisian"/utf8>>}
    ]},
    {<<"ga">>, [
        {language, <<"ga">>},
        {name, <<"Gaeilge"/utf8>>},
        {name_en, <<"Gaelic"/utf8>>}
    ]},
    {<<"gd">>, [
        {language, <<"gd">>},
        {region, <<"GB">>},
        {name, <<"Gàidhlig"/utf8>>},
        {name_en, <<"Scottish Gaelic"/utf8>>}
    ]},
    {<<"gl">>, [
        {language, <<"gl">>},
        {region, <<"ES">>},
        {name, <<"Galego"/utf8>>},
        {name_en, <<"Galician"/utf8>>}
    ]},
    {<<"gn">>, [
        {language, <<"gn">>},
        {region, <<"PY">>},
        {name, <<"Avañe'ẽ"/utf8>>},
        {name_en, <<"Guarani"/utf8>>}
    ]},
    {<<"gu">>, [
        {language, <<"gu">>},
        {script, <<"Gujr">>},
        {name, <<"ગુજરાતી"/utf8>>},
        {name_en, <<"Gujarati"/utf8>>}
    ]},
    {<<"he">>, [
        {language, <<"he">>},
        {direction, <<"RTL">>},
        {script, <<"Hebr">>},
        {region, <<"IL">>},
        {name, <<"עברית"/utf8>>},
        {name_en, <<"Hebrew"/utf8>>}
    ]},
    {<<"hi">>, [
        {language, <<"hi">>},
        {script, <<"Deva">>},
        {name, <<"हिन्दी"/utf8>>},
        {name_en, <<"Hindi"/utf8>>}
    ]},
    {<<"hr">>, [
        {language, <<"hr">>},
        {name, <<"Hrvatski"/utf8>>},
        {name_en, <<"Croatian"/utf8>>},
        {sublanguages, [
            {<<"hr-ba">>, [
                {language, <<"hr">>},
                {region, <<"BA">>},
                {name, <<"hrvatski - Bosna i Hercegovina"/utf8>>},
                {name_en, <<"Croatian - Bosnia and Herzegovina"/utf8>>}
            ]},
            {<<"hr-hr">>, [
                {language, <<"hr">>},
                {region, <<"HR">>},
                {name, <<"hrvatski - Hrvatska"/utf8>>},
                {name_en, <<"Croatian - Croatia"/utf8>>}
            ]}
        ]}
    ]},
    {<<"hu">>, [
        {language, <<"hu">>},
        {name, <<"Magyar"/utf8>>},
        {name_en, <<"Hungarian"/utf8>>}
    ]},
    {<<"id">>, [
        {language, <<"id">>},
        {region, <<"ID">>},
        {name, <<"Indonesia"/utf8>>},
        {name_en, <<"Indonesian"/utf8>>}
    ]},
    {<<"ia">>, [
        {language, <<"ia">>},
        {name, <<"Interlingua"/utf8>>},
        {name_en, <<"Interlingua"/utf8>>}
    ]},
    {<<"is">>, [
        {language, <<"is">>},
        {region, <<"IS">>},
        {name, <<"Íslenska"/utf8>>},
        {name_en, <<"Islandic"/utf8>>}
    ]},
    {<<"it">>, [
        {language, <<"it">>},
        {name, <<"Italiano"/utf8>>},
        {name_en, <<"Italian"/utf8>>},
        {sublanguages, [
            {<<"it-ch">>, [
                {language, <<"it">>},
                {region, <<"CH">>},
                {name, <<"italiano - Svizzera"/utf8>>},
                {name_en, <<"Italian - Switzerland"/utf8>>}
            ]},
            {<<"it-it">>, [
                {language, <<"it">>},
                {region, <<"IT">>},
                {name, <<"italiano - Italia"/utf8>>},
                {name_en, <<"Italian - Italy"/utf8>>}
            ]}
        ]}
    ]},
    {<<"ja">>, [
        {language, <<"ja">>},
        {script, <<"Jpan">>}, % alias for Han + Hiragana + Katakana
        {name, <<"日本語"/utf8>>},
        {name_en, <<"Japanese"/utf8>>}
    ]},
    {<<"jv">>, [
        {language, <<"jv">>},
        {region, <<"ID">>},
        {name, <<"Basa jawa"/utf8>>},
        {name_en, <<"Javanese"/utf8>>}
    ]},
    {<<"ka">>, [
        {language, <<"ka">>},
        {script, <<"Geor">>},
        {region, <<"GE">>},
        {name, <<"ქართული"/utf8>>},
        {name_en, <<"Georgian"/utf8>>}
    ]},
    {<<"ko">>, [
        {language, <<"ko">>},
        {script, <<"Kore">>},
        {name, <<"한국어"/utf8>>},
        {name_en, <<"Korean"/utf8>>}
    ]},
    {<<"ku">>, [
        {language, <<"ku">>},
        {name, <<"Kurdî‎"/utf8>>},
        {name_en, <<"Kurdish"/utf8>>}
    ]},
    {<<"lt">>, [
        {language, <<"lt">>},
        {name, <<"Lietuvių"/utf8>>},
        {name_en, <<"Lithuanian"/utf8>>}
    ]},
    {<<"lv">>, [
        {language, <<"lv">>},
        {region, <<"LV">>},
        {name, <<"Latviešu"/utf8>>},
        {name_en, <<"Latvian"/utf8>>}
    ]},
    {<<"mg">>, [
        {language, <<"mg">>},
        {region, <<"MG">>},
        {name, <<"Malagasy"/utf8>>},
        {name_en, <<"Malagasy"/utf8>>}
    ]},
    {<<"mk">>, [
        {language, <<"mk">>},
        {region, <<"MK">>},
        {script, <<"Cyrl">>},
        {name, <<"македонски"/utf8>>},
        {name_en, <<"Macedonian"/utf8>>}
    ]},
    {<<"mn">>, [
        {language, <<"mn">>},
        {name, <<"монгол"/utf8>>},
        {name_en, <<"Mongolian"/utf8>>}
    ]},
    {<<"mt">>, [
        {language, <<"mt">>},
        {region, <<"MT">>},
        {name, <<"Malti"/utf8>>},
        {name_en, <<"Maltese"/utf8>>}
    ]},
    {<<"ms">>, [
        {language, <<"ms">>},
        {name, <<"Malay"/utf8>>},
        {name_en, <<"Malay"/utf8>>}
    ]},
    {<<"nl">>, [
        {language, <<"nl">>},
        {name, <<"Nederlands"/utf8>>},
        {name_en, <<"Dutch"/utf8>>},
        {sublanguages, [
            {<<"nl-be">>, [
                {language, <<"nl">>},
                {region, <<"BE">>},
                {name, <<"Vlaams - België"/utf8>>},
                {name_en, <<"Flemish - Belgium"/utf8>>}
            ]},
            {<<"nl-nl">>, [
                {language, <<"nl">>},
                {region, <<"NL">>},
                {name, <<"Nederlands - Nederland"/utf8>>},
                {name_en, <<"Dutch - Netherlands"/utf8>>}
            ]}
        ]}
    ]},
    {<<"no">>, [
        {language, <<"no">>},
        {name, <<"Norsk"/utf8>>},
        {name_en, <<"Norwegian"/utf8>>}
    ]},
    {<<"nn">>, [
        {language, <<"nn">>},
        {region, <<"NO">>},
        {name, <<"nynorsk"/utf8>>},
        {name_en, <<"Norwegian Nynorsk"/utf8>>}
    ]},
    {<<"pa">>, [
        {language, <<"pa">>},
        {script, <<"Arab">>},
        {name, <<"ਪੰਜਾਬੀ"/utf8>>},
        {name_en, <<"Punjabi"/utf8>>},
        {sublanguages, [
            {<<"pa-arab">>, [
                {language, <<"pa">>},
                {script, <<"Arab">>},
                {name, <<"ابی"/utf8>>},
                {name_en, <<"Punjabi - Arab"/utf8>>}
            ]},
            {<<"pa-guru">>, [
                {language, <<"pa">>},
                {script, <<"Guru">>},
                {name, <<"ਪੰਜਾਬੀ ਦੇ - ਗੁਰਮੁਖੀ"/utf8>>},
                {name_en, <<"Punjabi - Arab"/utf8>>}
            ]}
        ]}
    ]},
    {<<"pl">>, [
        {language, <<"pl">>},
        {region, <<"PL">>},
        {name, <<"Polski"/utf8>>},
        {name_en, <<"Polish"/utf8>>}
    ]},
    {<<"ps">>, [
        {language, <<"ps">>},
        {script, <<"Arab">>},
        {name, <<"تو"/utf8>>},
        {name_en, <<"Pashto"/utf8>>}
    ]},
    {<<"pt">>, [
        {language, <<"pt">>},
        {name, <<"Português"/utf8>>},
        {name_en, <<"Portuguese"/utf8>>},
        {sublanguages, [
            {<<"pt-br">>, [
                {language, <<"pt">>},
                {region, <<"BR">>},
                {name, <<"Português - Brasil"/utf8>>},
                {name_en, <<"Portuguese - Brazil"/utf8>>}
            ]},
            {<<"pt-pt">>, [
                {language, <<"pt">>},
                {region, <<"PT">>},
                {name, <<"Português - Portugal"/utf8>>},
                {name_en, <<"Portuguese - Portugal"/utf8>>}
            ]}
        ]}
    ]},
    {<<"ro">>, [
        {language, <<"ro">>},
        {name, <<"Română"/utf8>>},
        {name_en, <<"Romanian"/utf8>>}
    ]},
    {<<"ru">>, [
        {language, <<"ru">>},
        {script, <<"Cyrl">>},
        {name, <<"русский язык"/utf8>>},
        {name_en, <<"Russian"/utf8>>}
    ]},
    {<<"si">>, [
        {language, <<"si">>},
        {name, <<"Sinhalese"/utf8>>},
        {name_en, <<"Sinhalese"/utf8>>}
    ]},
    {<<"sk">>, [
        {language, <<"sk">>},
        {name, <<"Slovenčina"/utf8>>},
        {name_en, <<"Slovak"/utf8>>}
    ]},
    {<<"sl">>, [
        {language, <<"sl">>},
        {name, <<"Slovenščina"/utf8>>},
        {name_en, <<"Slovenian"/utf8>>}
    ]},
    {<<"sr">>, [
        {language, <<"sr">>},
        {script, <<"Cyrl">>},
        {name, <<"српски"/utf8>>},
        {name_en, <<"Serbian"/utf8>>}
    ]},
    {<<"su">>, [
        {language, <<"su">>},
        {name, <<"Sundanese"/utf8>>},
        {name_en, <<"Sundanese"/utf8>>}
    ]},
    {<<"sv">>, [
        {language, <<"sv">>},
        {name, <<"Svenska"/utf8>>},
        {name_en, <<"Swedish"/utf8>>}
    ]},
    {<<"sw">>, [
        {language, <<"sw">>},
        {name, <<"Kiswahili"/utf8>>},
        {name_en, <<"Swahili"/utf8>>}
    ]},
    {<<"sq">>, [
        {language, <<"sq">>},
        {name, <<"Shqip"/utf8>>},
        {name_en, <<"Albanian"/utf8>>}
    ]},
    {<<"ta">>, [
        {language, <<"ta">>},
        {name, <<"Tamil"/utf8>>},
        {name_en, <<"Tamil"/utf8>>}
    ]},
    {<<"th">>, [
        {language, <<"th">>},
        {script, <<"Thai">>},
        {name, <<"ไทย"/utf8>>},
        {name_en, <<"Thai"/utf8>>}
    ]},
    {<<"tl">>, [
        {language, <<"tl">>},
        {name, <<"Tagalog"/utf8>>},
        {name_en, <<"Tagalog"/utf8>>}
    ]},
    {<<"tr">>, [
        {language, <<"tr">>},
        {name, <<"Türkçe"/utf8>>},
        {name_en, <<"Turkish"/utf8>>}
    ]},
    {<<"uk">>, [
        {language, <<"uk">>},
        {script, <<"Cyrl">>},
        {name, <<"українська"/utf8>>},
        {name_en, <<"Ukrainian"/utf8>>}
    ]},
    {<<"ur">>, [
        {language, <<"ur">>},
        % {script, <<"Nastaʼlīq"/utf8>>},
        {name, <<"اُردُو"/utf8>>},
        {name_en, <<"Urdu"/utf8>>}
    ]},
    {<<"vi">>, [
        {language, <<"vi">>},
        {region, <<"VN">>},
        {name, <<"Tiếng Việt"/utf8>>},
        {name_en, <<"Vietnamese"/utf8>>}
    ]},
    {<<"xh">>, [
        {language, <<"xh">>},
        {name, <<"Xhosa"/utf8>>},
        {name_en, <<"Xhosa"/utf8>>}
    ]},
    {<<"yo">>, [
        {language, <<"yo">>},
        {name, <<"Èdè Yorùbá"/utf8>>},
        {name_en, <<"Yoruba"/utf8>>}
    ]},
    {<<"zh">>, [
        {language, <<"zh">>},
        {alias, [
            <<"zh-hans">>,
            <<"zh-hans-cn">>, <<"zh-cn">>,
            <<"zh-hans-sg">>, <<"zh-sg">>
        ]},
        {script, <<"Hans">>},
        {name, <<"中文"/utf8>>},
        {name_en, <<"Chinese (Simplified)"/utf8>>},
        {fallback, <<"zh-hant">>}
    ]},
    {<<"zh-hant">>, [
        {language, <<"zh-hant">>},
        {alias, [
            <<"zh-hk">>, <<"zh-hant-hk">>,
            <<"zh-tw">>, <<"zh-hant-tw">>,
            <<"zh-mo">>, <<"zh-hant-mo">>
        ]},
        {script, <<"Hant">>},
        {name, <<"中國傳統的腳本"/utf8>>},
        {name_en, <<"Chinese (Traditional)"/utf8>>},
        {fallback, <<"zh">>}
    ]}
].



%% Other, less used languages:

% gv: Manx
% ha: Hausa
% ho: Hiri Motu
% hy: Armenian
% hz: Herero
% ik: Inupiak
% io: Ido
% iu: Inuktitut
% ki: Kikuyu
% kj: Kuanyama
% kk: Kazakh
% kl: Kalaallisut Greenlandic
% km: Khmer Cambodian
% kn: Kannada
% ks: Kashmiri
% kv: Komi
% kw: Cornish
% ky: Kirghiz
% lb: Letzeburgesch
% ln: Lingala
% lo: Lao Laotian
% mh: Marshall
% mi: Maori
% ml: Malayalam
% mo: Moldavian
% mr: Marathi
% my: Burmese
% na: Nauru
% nb: Norwegian Bokmål
% nd: Ndebele, North
% ne: Nepali
% ng: Ndonga
% nr: Ndebele, South
% nv: Navajo
% ny: Chichewa Nyanja
% oc: Occitan Provençal
% om: (Afan) Oromo
% or: Oriya
% os: Ossetian Ossetic
% pi: Pali
% qu: Quechua
% rm: Rhaeto-Romance
% rn: Rundi Kirundi
% rw: Kinyarwanda
% sa: Sanskrit
% sc: Sardinian
% sd: Sindhi
% se: Northern Sami
% sg: Sango Sangro
% sm: Samoan
% sn: Shona
% so: Somali
% ss: Swati Siswati
% st: Sesotho Sotho, Southern
% te: Telugu
% tg: Tajik
% ti: Tigrinya
% tk: Turkmen
% tn: Tswana Setswana
% to: Tonga
% ts: Tsonga
% tt: Tatar
% tw: Twi
% ty: Tahitian
% ug: Uighur
% uz: Uzbek
% vo: Volapuk
% wa: Walloon
% wo: Wolof
% za: Zhuang
% zu: Zulu