Add localizations for romanian and hungarian

Change-Id: Icdfb1b951f0797f180ab3ad0b32c299647f5d6a2
diff --git a/Changes b/Changes
index 11a514d..e27a836 100644
--- a/Changes
+++ b/Changes
@@ -10,7 +10,9 @@
         - Support setting of query form elements via plugins (diewald)
         - Fix h1-logo (only visible in header; diewald)
         - Added translations for CQL (r-wilm)
- 
+        - Partial support for romanian (irimia) and hungarian
+          (pfischer) localizations
+
 0.57 2024-10-08
         - Support VCs via URL without queries (diewald)
         - Added translations for regexp and FCSQL (r-wilm)
diff --git a/lib/Kalamar.pm b/lib/Kalamar.pm
index 8d6ba8c..d2f6718 100644
--- a/lib/Kalamar.pm
+++ b/lib/Kalamar.pm
@@ -241,7 +241,12 @@
         _ => sub { shift->config('Kalamar')->{'examplecorpus'} },
       }
     },
-    resources => ['kalamar.dict', 'kalamar.queries.dict']
+    resources => [
+      'kalamar.dict',
+      'kalamar.queries.dict',
+      'loc/kalamar.ro.dict',
+      'loc/kalamar.hu.dict'
+    ]
   });
 
   # Pagination widget
diff --git a/loc/kalamar.hu.dict b/loc/kalamar.hu.dict
new file mode 100644
index 0000000..5d2741c
--- /dev/null
+++ b/loc/kalamar.hu.dict
@@ -0,0 +1,137 @@
+# Dictionary template generated Tue, 22 Oct 2024 14:54:48 GMT
+
+{
+  "Auth_hu_accessToken" => "Hozzáférési token",
+  "Auth_hu_authenticationFail" => "Nem hitelesített",
+  "Auth_hu_clientCredentials" => "Ügyfél hitelesítő adatok",
+  "Auth_hu_clientID" => "Ügyfélalkalmazás azonosítója",
+  "Auth_hu_clientIDFail" => "Ügyfél azonosító szükséges",
+  "Auth_hu_clientName" => "Ügyfélalkalmazás neve",
+  "Auth_hu_clientRegister" => "Új ügyfélalkalmazás regisztrálása",
+  "Auth_hu_clientSecret" => "Ügyféltitok",
+  "Auth_hu_clientType" => "Ügyfélalkalmazás típusa",
+  "Auth_hu_confidentialRequired" => "Pluginoknak bizalmasnak kell lenniük",
+  "Auth_hu_createdAt" => "Létrejött <time datetime=\"<%= stash(\"date\") %>\"><%= stash(\"date\") %></date> napján.",
+  "Auth_hu_csrfFail" => "Rossz CSRF-token",
+  "Auth_hu_desc" => "Rövid leírás",
+  "Auth_hu_expiresIn" => "<%= stash(\"seconds\") %> másodperc múlva lejár.",
+  "Auth_hu_fileSizeExceeded" => "Fájlméret túllépve",
+  "Auth_hu_homepage" => "Honlap",
+  "Auth_hu_install" => "Telepítés",
+  "Auth_hu_installFail" => "A plugin telepítése nem sikerült",
+  "Auth_hu_instdate" => "Telepítés dátuma",
+  "Auth_hu_instplugins" => "Telepített pluginok",
+  "Auth_hu_invalidChar" => "Érvénytelen karaktert tartalmaz",
+  "Auth_hu_jsonRequired" => "Plugin deklarációknak json fájloknak kell lenniük",
+  "Auth_hu_loginFail" => "Hozzáférés elutasítva",
+  "Auth_hu_loginHint" => "Lehet, hogy először be kell jelentkeznie?",
+  "Auth_hu_loginPlease" => "Kérjük, jelentkezzen be!",
+  "Auth_hu_loginSuccess" => "Bejelentkezés sikerült",
+  "Auth_hu_logoutFail" => "Kijelentkezés nem sikerült",
+  "Auth_hu_logoutSuccess" => "Kijelentkezés sikerült",
+  "Auth_hu_marketplace" => "Piactér",
+  "Auth_hu_marketplaceFail_-long" => "Pluginok megjelenítese nem sikerült.",
+  "Auth_hu_marketplaceFail_short" => "Próbálja újra",
+  "Auth_hu_oauthGrantPublicWarn" => "Figyelem - ez egy nyilvános ügyfél!",
+  "Auth_hu_oauthGrantRedirectWarn" => "Az átirányítás ismeretlen helyre mutat",
+  "Auth_hu_oauthGrantScope_-long" => '<span class="client-name"><%= $client_name %></span> hozzáférést szeretne kapni',
+  "Auth_hu_oauthGrantScope_short" => "Hozzáférés engedélyezése",
+  "Auth_hu_oauthHint" => "Az API-ügyfelek alábbi regisztrációja az <a href=\"https://oauth.net/\" class=\"external\">OAuth 2.0 specifikáció</a> szerint történik.",
+  "Auth_hu_oauthIssueToken_-long" => 'Új token kiadása <span class="client-name"><%= $client_name %></span> ügyfél számára',
+  "Auth_hu_oauthIssueToken_short" => "Új token kiadása",
+  "Auth_hu_oauthRevokeToken_-long" => '<span class="client-name"><%= $client_name %></span> számára kiadott token visszavonása'
+   ,
+  "Auth_hu_oauthRevokeToken_short" => "Token visszavonása",
+  "Auth_hu_oauthSettings" => "OAuth",
+  "Auth_hu_oauthUnregister_-long" => '<span class="client-name"><%= $client_name %></span> ügyfél regisztráció törlése?',
+  "Auth_hu_oauthUnregister_short" => "Regisztráció törlése",
+  "Auth_hu_openRedirectFail" => "Átirányítási hiba",
+  "Auth_hu_paramError" => "Néhány mező érvénytelen",
+  "Auth_hu_plugins" => "Pluginok",
+  "Auth_hu_pluginSrc" => "Plugin deklaráció (*.json fájl)",
+  "Auth_hu_redirectUri" => "Átirányítási URI",
+  "Auth_hu_refreshFail" => "Rossz frissítő token",
+  "Auth_hu_regby" => "Regisztrálta",
+  "Auth_hu_regdate" => "Regisztráció dátuma",
+  "Auth_hu_registerFail" => "Regisztráció elutasítva",
+  "Auth_hu_registerSuccess" => "Regisztráció sikerült",
+  "Auth_hu_responseError" => "Ismeretlen hitelesítési hiba",
+  "Auth_hu_revoke" => "Visszavonás",
+  "Auth_hu_revokeFail" => "Token nem vonható vissza",
+  "Auth_hu_revokeSuccess" => "Token visszavonása sikerült",
+  "Auth_hu_scopeFail" => "Scope szükséges",
+  "Auth_hu_serverError" => "Ismeretlen szerver hiba",
+  "Auth_hu_tokenExpired" => "Hozzáférési token lejárt",
+  "Auth_hu_tokenInvalid" => "Hozzáférési token érvénytelen",
+  "Auth_hu_uninstall" => "Plugin törlése",
+  "Auth_hu_uninstallFail" => "Plugin törlése nem sikerült",
+  "hu_abort" => "Mégse",
+  "hu_about" => "KorAP-ról",
+  "hu_activateJS" => "A teljes funkciókészlet használatához aktiválja a JavaScriptet!",
+  "hu_backendNotAvailable" => "Backend nem elérhető a <code><%= app->korap->api %></code> címen!",
+  # "hu_by" => "by",
+  "hu_email" => "Email",
+  "hu_faq" => "GYIK",
+  "hu_glimpse_-short" => "Pillantás",
+  "hu_glimpse_desc" => "Csak az első találatok megjelenítése önhatalmú sorrendben",
+  # "hu_go" => "Go!",
+  "hu_imprint" => "Impresszum",
+  # "hu_in" => "in",
+  # "hu_jsFile" => "kalamar-<%= $Kalamar::VERSION %>-hu.js",
+  "hu_korap_-short" => "KorAP",
+  "hu_korap_desc" => "<%= loc \"korap_label\" %> - Korpuszelemző platform",
+  # "hu_korap_keywords" => "KorAP, DeReKo, Corpus Query Platform, IDS Mannheim, Leibniz Institute for the German Language",
+  # "hu_korap_label" => "<%= loc \"korap_short\" %><% if (loc(\"title_addon\")) { %>-<%= loc(\"title_addon\") %><% } %>",
+  "hu_korap_overview" => "<%= loc \"korap_label\" %> - Áttekintő",
+  "hu_korap_placename" => "Mannheim",
+  # "hu_korap_region" => "DE-BW",
+  "hu_login" => "Bejelentkezés",
+  "hu_logout" => "Kijelentkezés",
+  "hu_maintenanceWork_desc" => "Karbantartási munkálatok miatt a szolgáltatás szünetel.",
+  "hu_maintenanceWork_time" => "Karbantartás",
+  "hu_matchCount" => "találat",
+  "hu_Nav_#annotation-operators" => "Annotációs operátorok",
+  "hu_Nav_#area-operators" => "Körzeti operátorok",
+  "hu_Nav_#class-operators" => "Szófaji operátorok ",
+  "hu_Nav_#combination-operators" => "Kombinációs operátorok",
+  "hu_Nav_#complex" => "Összetett szegmensek",
+  "hu_Nav_#default-foundries" => "Alapöntödék",
+  "hu_Nav_#distance-operators" => "Távolsági operátorok",
+  "hu_Nav_#logical-operators" => "Logikai operátorok",
+  "hu_Nav_#paradigmatic-operators" => "Paradigmatikai operátorok",
+  "hu_Nav_#queryterms" => "Lekérdezési kifejezések",
+  "hu_Nav_#segments" => "Egyszerű szegmensek",
+  "hu_Nav_#spans" => "Hosszú szegmensek",
+  "hu_Nav_#syntagmatic-operators" => "Szintagmatikai operátorok",
+  "hu_Nav_annotation" => "Annotációk",
+  "hu_Nav_corpus" => "Korpuszok",
+  "hu_Nav_data" => "Korpusz adatok",
+  "hu_Nav_development" => "Fejlesztés",
+  "hu_Nav_faq" => "GYIK",
+  "hu_Nav_ql" => "Lekérdezési nyelvek",
+  "hu_Nav_regexp" => "Reguláris kifejezés",
+  "hu_news" => "Hírek",
+  "hu_noMatches" => "Nincs találat a <%== loc(\"searchjob\") %> kifejezésre.",
+  "hu_notAvailInCorpus" => "Nem elérhető a jelenlegi korpuszban",
+  "hu_notFound" => "404 - Oldal nem elérhető",
+  "hu_notIssued" => "Végrehajtás nem sikerült.",
+  "hu_oclock" => "órakor",
+  # "hu_page_-sg" => "p.",
+  # "hu_page_pl" => "pp.",
+  "hu_privacy" => "Adatvédelem",
+  "hu_pubOn" => "megjelent",
+  "hu_pwd" => "Jelszó",
+  "hu_pwdforgotten" => "Elfelejtette a jelszavát?",
+  "hu_QL_cqp" => "CQP (új)",
+  "hu_register" => "Regisztráció",
+  "hu_searchjob" => '»<%== $q %>« <% if (param("collection")) { %>a meghatározott korpuszban <% } %><%== loc("QL_". $ql, "egy ismeretlen") %> lekérdezési nyelvvel',
+  # "hu_searchplaceholder" => "Find ...",
+  # "hu_searchtitle" => "<%= loc(\"korap_label\") %>: Find <%== loc(\"searchjob\") %>",
+  "hu_settings" => "Beállítások",
+  "hu_tutorial" => "Súgó és dokumentáció",
+  "hu_underConstruction" => "Karbantartás!",
+  "hu_upload" => "Feltöltés",
+  "hu_username" => "Felhasználónév",
+  "hu_userormail" => "Felhasználónév vagy email",
+  # "hu_with" => "with",
+};
diff --git a/loc/kalamar.ro.dict b/loc/kalamar.ro.dict
new file mode 100644
index 0000000..bcebb73
--- /dev/null
+++ b/loc/kalamar.ro.dict
@@ -0,0 +1,68 @@
+{
+  "ro_about" => \"Despre KorAP",
+  "ro_activateJS" => \"Pentru a putea avea acces la toate funcționalitățile plarformei, activați JavaScript!",
+  # "ro_Auth_csrfFail" => \"Bad CSRF token",
+  "Auth_ro_loginFail" => \"Acces interzis",
+  "Auth_ro_loginSuccess" => \"Autentificare reușită",
+  "Auth_ro_logoutFail" => \"Autentificare eșuată",
+  "Auth_ro_logoutSuccess" => \"Deconectare reușită",
+  "Auth_ro_openRedirectFail" => \"Eroare de redirecționare",
+  "ro_by" => \"de",
+  "ro_email" => \"Email",
+  "ro_faq" => \"F.A.Q.",
+  "ro_glimpse_desc" => \"Afișează doar primele rezultate în ordine arbitrară",
+  "ro_glimpse_-short" => \"Aruncă o privire",
+  "ro_go" => \"Caută!",
+  "ro_imprint" => \"Imprint",
+  "ro_in" => \"în",
+  # "ro_jsFile" => "kalamar-<%= $Kalamar::VERSION %>-en.js",
+  "ro_korap_desc" => \"KorAP - Platformă pentru analiza corpusului",
+  "ro_korap_overview" => \"KorAP - Prezentare generală",
+  "ro_korap_short" => \"KorAP",
+  "ro_login" => \"Login",
+  "ro_logout" => \"Logout",
+  # "ro_matchCount" => "<%= quant($found, \"match\", \"matches\") %>",
+  "ro_Nav_#class-operators" => \"Operatori Class",
+  "ro_Nav_#complex" => \"Segmente complexe",
+  "ro_Nav_#default-foundries" => \"Foundries implicite",
+  "ro_Nav_#paradigmatic-operators" => \"Operatori paradigmatici",
+  "ro_Nav_#segments" => \"Segmente simple",
+  "ro_Nav_#spans" => \"Segmente span",
+  "ro_Nav_#syntagmatic-operators" => \"Operatori sintagmatici",
+  "ro_Nav_annotation" => \"Adnotări",
+  "ro_Nav_corpus" => \"Corpusuri",
+  "ro_Nav_data" => \"Date",
+  "ro_Nav_faq" => \"Întrebări frecvente",
+  "ro_Nav_ql" => \"Limbaje de interogare",
+  "ro_Nav_regexp" => \"Expresii regulate",
+  "ro_noMatches" => "Nu s-au găsit rezultate pentru <%== loc(\"searchjob\") %>.",
+  "ro_notAvailInCorpus" => \"NU este disponibil în corpusul actual",
+  "ro_notFound" => \"404 - Pagina nu a fost găsită",
+  # "ro_numf" => sub { ... },
+  "ro_privacy" => \"Confidențialitate",
+  "ro_pubOn" => \"publicat în",
+  "ro_pwd" => \"Parola",
+  "ro_pwdforgotten" => \"Ați uitat parola?",
+  # "ro_QL_annis" => \"Annis QL",
+  # "ro_QL_cosmas2" => \"Cosmas II",
+  # "ro_QL_cql" => \"CQL v1.2",
+  # "ro_QL_fcsql" => \"FCSQL",
+  # "ro_QL_poliqarp" => \"Poliqarp",
+  "ro_register" => \"Înregistrați-vă!",
+  # searchjob => '»<%== $q %>« <% if (param("collection-name")) { %>in »<%== param("collection-name") %>« <% } elsif (param("collection")) { %>im definierten Korpus <% } %>mit <%== loc("QL_" . $ql, "unbekannter Anfragesprache") %>',
+  # "ro_searchplaceholder" => \"Find ...",
+  "ro_searchtitle" => "KorAP: Caută <%== loc(\"searchjob\") %>",
+  # "ro_Template_doc_api_koralquery" => \"doc/api/koralquery",
+  # "ro_Template_doc_data_annotation" => \"doc/data/annotation",
+  # "ro_Template_doc_korap_kalamar" => \"doc/korap/kalamar",
+  # "ro_Template_doc_korap_karang" => \"doc/korap/karang",
+  # "ro_Template_doc_korap_koral" => \"doc/korap/koral",
+  # "ro_Template_doc_korap_krill" => \"doc/korap/krill",
+  # "ro_Template_doc_korap_kustvakt" => \"doc/korap/kustvakt",
+  # "ro_Template_doc_ql_poliqarp-plus" => \"doc/ql/poliqarp-plus",
+  # "ro_Template_intro" => \"intro",
+  # "ro_tutorial" => \"Manual",
+  "ro_underConstruction" => \"În lucru!",
+  "ro_userormail" => \"Nume de utilizator sau Email",
+  "ro_with" => \"cu",
+};
\ No newline at end of file
diff --git a/t/loc.t b/t/loc.t
new file mode 100644
index 0000000..3b45795
--- /dev/null
+++ b/t/loc.t
@@ -0,0 +1,38 @@
+use Mojo::Base -strict;
+use Test::More;
+use Test::Mojo;
+use Mojo::File qw/path/;
+use utf8;
+
+$ENV{KALAMAR_VERSION} = '0.47.999';
+
+my $t = Test::Mojo->new('Kalamar');
+
+$t->app->mode('production');
+
+$t->get_ok('/')
+  ->status_is(200)
+  ->text_is('title', 'KorAP - Corpus Analysis Platform')
+  ->text_is('h1 span', 'KorAP - Corpus Analysis Platform')
+  ;
+
+$t->get_ok('/' => { 'Accept-Language' => 'de-DE, en-US, en' })
+  ->status_is(200)
+  ->text_is('title', 'KorAP - Korpusanalyseplattform der nächsten Generation')
+  ->text_is('h1 span', 'KorAP - Korpusanalyseplattform der nächsten Generation')
+  ;
+
+$t->get_ok('/' => { 'Accept-Language' => 'ro, en' })
+  ->status_is(200)
+  ->text_is('title', 'KorAP - Platformă pentru analiza corpusului')
+  ->text_is('h1 span', 'KorAP - Platformă pentru analiza corpusului')
+  ;
+
+$t->get_ok('/' => { 'Accept-Language' => 'hu, en' })
+  ->status_is(200)
+  ->text_is('title', 'KorAP - Korpuszelemző platform')
+  ->text_is('h1 span', 'KorAP - Korpuszelemző platform')
+  ;
+
+
+done_testing();