From 3273c65ef82123bf5edbe6d8616630b20a993ce1 Mon Sep 17 00:00:00 2001 From: Thomas Voss Date: Sun, 11 Aug 2024 03:13:10 +0200 Subject: Giant refactoring of the codebase --- .exrc | 4 +- .gitignore | 2 +- Makefile | 4 +- cmd/mfmt/main.go | 2 +- cmd/mfmt/util_test.go | 2 +- i18n/locales/bg/messages.gotext.json | 434 ---------------------- i18n/locales/el/messages.gotext.json | 434 ---------------------- i18n/locales/en/messages.gotext.json | 580 ------------------------------ i18n/locales/nl/messages.gotext.json | 434 ---------------------- i18n/printer.go | 251 ------------- lib/countries.go | 46 +++ lib/i18n.go | 252 +++++++++++++ lib/locales/bg/messages.gotext.json | 515 ++++++++++++++++++++++++++ lib/locales/el/messages.gotext.json | 515 ++++++++++++++++++++++++++ lib/locales/en/messages.gotext.json | 679 +++++++++++++++++++++++++++++++++++ lib/locales/nl/messages.gotext.json | 515 ++++++++++++++++++++++++++ lib/mintage/parser.go | 207 +++++++++++ lib/mintage/parser_test.go | 280 +++++++++++++++ main.go | 82 ++++- middleware/i18n.go | 42 --- mintage/parser.go | 207 ----------- mintage/parser_test.go | 280 --------------- template/about.templ | 52 +++ template/base.go | 3 + template/base.templ | 51 +++ template/coins.templ | 53 +++ template/coins_designs.templ | 41 +++ template/coins_designs_nl.templ | 43 +++ template/coins_mintages.templ | 112 ++++++ template/language.templ | 54 +++ template/navbar.templ | 241 +++++++++++++ template/root.templ | 23 ++ templates/about.templ | 52 --- templates/base.go | 63 ---- templates/base.templ | 59 --- templates/coins.templ | 53 --- templates/coins_designs.templ | 41 --- templates/coins_designs_nl.templ | 43 --- templates/language.templ | 54 --- templates/navbar.templ | 241 ------------- templates/root.templ | 23 -- 41 files changed, 3756 insertions(+), 3313 deletions(-) delete mode 100644 i18n/locales/bg/messages.gotext.json delete mode 100644 i18n/locales/el/messages.gotext.json delete mode 100644 i18n/locales/en/messages.gotext.json delete mode 100644 i18n/locales/nl/messages.gotext.json delete mode 100644 i18n/printer.go create mode 100644 lib/countries.go create mode 100644 lib/i18n.go create mode 100644 lib/locales/bg/messages.gotext.json create mode 100644 lib/locales/el/messages.gotext.json create mode 100644 lib/locales/en/messages.gotext.json create mode 100644 lib/locales/nl/messages.gotext.json create mode 100644 lib/mintage/parser.go create mode 100644 lib/mintage/parser_test.go delete mode 100644 middleware/i18n.go delete mode 100644 mintage/parser.go delete mode 100644 mintage/parser_test.go create mode 100644 template/about.templ create mode 100644 template/base.go create mode 100644 template/base.templ create mode 100644 template/coins.templ create mode 100644 template/coins_designs.templ create mode 100644 template/coins_designs_nl.templ create mode 100644 template/coins_mintages.templ create mode 100644 template/language.templ create mode 100644 template/navbar.templ create mode 100644 template/root.templ delete mode 100644 templates/about.templ delete mode 100644 templates/base.go delete mode 100644 templates/base.templ delete mode 100644 templates/coins.templ delete mode 100644 templates/coins_designs.templ delete mode 100644 templates/coins_designs_nl.templ delete mode 100644 templates/language.templ delete mode 100644 templates/navbar.templ delete mode 100644 templates/root.templ diff --git a/.exrc b/.exrc index 858eea9..f67ec8e 100644 --- a/.exrc +++ b/.exrc @@ -26,5 +26,5 @@ autocmd FileType templ autocmd BufWritePre nnoremap gM :wall \| make all-i18n nnoremap t :vimgrep /\CTODO/ **/* -let &wildignore = netrw_gitignore#Hide() . ',catalog.go,*_templ.go,.git/*,vendor/*' -let g:netrw_list_hide .= ",catalog.go,.*_templ\\.go$" +let &wildignore = netrw_gitignore#Hide() . ',.git/*,vendor/*' +let g:netrw_list_hide .= ",.*\\.gen\\..*,.*_templ\\.go$" diff --git a/.gitignore b/.gitignore index c7fa2cf..e58bfc9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ euro-cash.eu -i18n/catalog.go mfmt !cmd/mfmt out.gotext.json +*.gen.* *_templ.go diff --git a/Makefile b/Makefile index e9106cb..85ba3d9 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,10 @@ # Generating translations is rather slow; so don’t do that by default all: - TEMPL_EXPERIMENT=rawgo go generate ./templates + TEMPL_EXPERIMENT=rawgo go generate ./template go build all-i18n: - TEMPL_EXPERIMENT=rawgo go generate ./templates ./i18n + TEMPL_EXPERIMENT=rawgo go generate ./template ./lib find . -name out.gotext.json | mcp -b sed s/out/messages/ go build diff --git a/cmd/mfmt/main.go b/cmd/mfmt/main.go index 3144372..cb9b0cd 100644 --- a/cmd/mfmt/main.go +++ b/cmd/mfmt/main.go @@ -7,7 +7,7 @@ import ( "path/filepath" "unsafe" - "git.thomasvoss.com/euro-cash.eu/mintage" + "git.thomasvoss.com/euro-cash.eu/lib/mintage" ) const cols = unsafe.Sizeof(mintage.Row{}.Cols) / diff --git a/cmd/mfmt/util_test.go b/cmd/mfmt/util_test.go index af97146..1041e4f 100644 --- a/cmd/mfmt/util_test.go +++ b/cmd/mfmt/util_test.go @@ -6,7 +6,7 @@ package main import ( "testing" - "git.thomasvoss.com/euro-cash.eu/mintage" + "git.thomasvoss.com/euro-cash.eu/lib/mintage" ) func TestFormatInt(t *testing.T) { diff --git a/i18n/locales/bg/messages.gotext.json b/i18n/locales/bg/messages.gotext.json deleted file mode 100644 index 0cb77fa..0000000 --- a/i18n/locales/bg/messages.gotext.json +++ /dev/null @@ -1,434 +0,0 @@ -{ - "language": "bg", - "messages": [ - { - "id": "Page not found", - "message": "Page not found", - "translation": "" - }, - { - "id": "About Us", - "message": "About Us", - "translation": "" - }, - { - "id": "Open Source", - "message": "Open Source", - "translation": "" - }, - { - "id": "This website is an open project, and a collaboration between developers, translators, and researchers. All source code, data, images, and more for the website are open source and can be found {RepoLinkStart}here{LinkEnd}. This site is licensed under the BSD 0-Clause license giving you the full freedom to do whatever you would like with any of the content on this site.", - "message": "This website is an open project, and a collaboration between developers, translators, and researchers. All source code, data, images, and more for the website are open source and can be found {RepoLinkStart}here{LinkEnd}. This site is licensed under the BSD 0-Clause license giving you the full freedom to do whatever you would like with any of the content on this site.", - "translation": "", - "placeholders": [ - { - "id": "RepoLinkStart", - "string": "%[1]s", - "type": "string", - "underlyingType": "string", - "argNum": 1, - "expr": "repoLinkStart" - }, - { - "id": "LinkEnd", - "string": "%[2]s", - "type": "string", - "underlyingType": "string", - "argNum": 2, - "expr": "linkEnd" - } - ] - }, - { - "id": "Contact Us", - "message": "Contact Us", - "translation": "" - }, - { - "id": "While we try to stay as up-to-date as possible and to fact check our information, it is always possible that we get something wrong, lack a translation, or are missing some piece of data you may have. In such a case don’t hesitate to contact us; we’ll try to get the site updated or fixed as soon as possible. You are always free to contribute via a git patch if you are more technically included, but if not you can always send an email to {ContactEmail} or contact ‘@onetruemangoman’ on Discord.", - "message": "While we try to stay as up-to-date as possible and to fact check our information, it is always possible that we get something wrong, lack a translation, or are missing some piece of data you may have. In such a case don’t hesitate to contact us; we’ll try to get the site updated or fixed as soon as possible. You are always free to contribute via a git patch if you are more technically included, but if not you can always send an email to {ContactEmail} or contact ‘@onetruemangoman’ on Discord.", - "translation": "", - "placeholders": [ - { - "id": "ContactEmail", - "string": "%[1]s", - "type": "string", - "underlyingType": "string", - "argNum": 1, - "expr": "contactEmail" - } - ] - }, - { - "id": "Special Thanks", - "message": "Special Thanks", - "translation": "" - }, - { - "id": "Development", - "message": "Development", - "translation": "" - }, - { - "id": "Research", - "message": "Research", - "translation": "" - }, - { - "id": "Translations", - "message": "Translations", - "translation": "" - }, - { - "id": "British- \u0026 American English", - "message": "British- \u0026 American English", - "translation": "" - }, - { - "id": "Icelandic", - "message": "Icelandic", - "translation": "" - }, - { - "id": "Andorra", - "message": "Andorra", - "translation": "Андора" - }, - { - "id": "Austria", - "message": "Austria", - "translation": "Австрия" - }, - { - "id": "Belgium", - "message": "Belgium", - "translation": "Белгия" - }, - { - "id": "Cyprus", - "message": "Cyprus", - "translation": "Кипър" - }, - { - "id": "Germany", - "message": "Germany", - "translation": "Германия" - }, - { - "id": "Estonia", - "message": "Estonia", - "translation": "Естония" - }, - { - "id": "Spain", - "message": "Spain", - "translation": "Испания" - }, - { - "id": "Finland", - "message": "Finland", - "translation": "Финландия" - }, - { - "id": "France", - "message": "France", - "translation": "Франция" - }, - { - "id": "Greece", - "message": "Greece", - "translation": "Гърция" - }, - { - "id": "Croatia", - "message": "Croatia", - "translation": "Хърватия" - }, - { - "id": "Ireland", - "message": "Ireland", - "translation": "Ирландия" - }, - { - "id": "Italy", - "message": "Italy", - "translation": "Италия" - }, - { - "id": "Lithuania", - "message": "Lithuania", - "translation": "Литва" - }, - { - "id": "Luxembourg", - "message": "Luxembourg", - "translation": "Люксембург" - }, - { - "id": "Latvia", - "message": "Latvia", - "translation": "Латвия" - }, - { - "id": "Monaco", - "message": "Monaco", - "translation": "Монако" - }, - { - "id": "Malta", - "message": "Malta", - "translation": "Малта" - }, - { - "id": "Netherlands", - "message": "Netherlands", - "translation": "Холандия" - }, - { - "id": "Portugal", - "message": "Portugal", - "translation": "Португалия" - }, - { - "id": "Slovenia", - "message": "Slovenia", - "translation": "Словения" - }, - { - "id": "Slovakia", - "message": "Slovakia", - "translation": "Словакия" - }, - { - "id": "San Marino", - "message": "San Marino", - "translation": "Сан Марино" - }, - { - "id": "Vatican City", - "message": "Vatican City", - "translation": "град Ватикана" - }, - { - "id": "Found a mistake or want to contribute missing information?", - "message": "Found a mistake or want to contribute missing information?", - "translation": "" - }, - { - "id": "Feel free to contact us!", - "message": "Feel free to contact us!", - "translation": "" - }, - { - "id": "Dutch Euro Coin Designs", - "message": "Dutch Euro Coin Designs", - "translation": "" - }, - { - "id": "From the years 1999–2013 all Dutch euro coins featured the portrait of Queen Beatrix of the Netherlands. After her abdication from the throne in 2013 the designs of all denominations were changed to feature the portrait of the new King Willem-Alexander. After her abdication the direction in which the monarchs portrait faced was flipped; a tradition dating back to the earliest coins of the Kingdom of the Netherlands.", - "message": "From the years 1999–2013 all Dutch euro coins featured the portrait of Queen Beatrix of the Netherlands. After her abdication from the throne in 2013 the designs of all denominations were changed to feature the portrait of the new King Willem-Alexander. After her abdication the direction in which the monarchs portrait faced was flipped; a tradition dating back to the earliest coins of the Kingdom of the Netherlands.", - "translation": "" - }, - { - "id": "Coins featuring both monarchs contain text reading ‘BEATRIX KONINGIN DER NEDERLANDEN’ (‘BEATRIX QUEEN OF THE NETHERLANDS’) and ‘Willem-Alexander Koning der Nederlanden’ (‘Willem-Alexander King of the Netherlands’) respectively.", - "message": "Coins featuring both monarchs contain text reading ‘BEATRIX KONINGIN DER NEDERLANDEN’ (‘BEATRIX QUEEN OF THE NETHERLANDS’) and ‘Willem-Alexander Koning der Nederlanden’ (‘Willem-Alexander King of the Netherlands’) respectively.", - "translation": "" - }, - { - "id": "The €1 and €2 coins featuring King Willem-Alexander were minted with a much lower relief than most euro coins of the same denomination. As a result it is not uncommon for these coins to appear worn after little use in circulation.", - "message": "The €1 and €2 coins featuring King Willem-Alexander were minted with a much lower relief than most euro coins of the same denomination. As a result it is not uncommon for these coins to appear worn after little use in circulation.", - "translation": "" - }, - { - "id": "Euro Coin Designs", - "message": "Euro Coin Designs", - "translation": "" - }, - { - "id": "Here you’ll be able to view all the coin designs for each country in the Eurozone. This section of the site doesn’t include minor varieties such as different mintmarks or errors; those are on the {VarietiesLinkStart}varieties{LinkEnd} page.", - "message": "Here you’ll be able to view all the coin designs for each country in the Eurozone. This section of the site doesn’t include minor varieties such as different mintmarks or errors; those are on the {VarietiesLinkStart}varieties{LinkEnd} page.", - "translation": "", - "placeholders": [ - { - "id": "VarietiesLinkStart", - "string": "%[1]s", - "type": "string", - "underlyingType": "string", - "argNum": 1, - "expr": "varietiesLinkStart" - }, - { - "id": "LinkEnd", - "string": "%[2]s", - "type": "string", - "underlyingType": "string", - "argNum": 2, - "expr": "linkEnd" - } - ] - }, - { - "id": "Euro Coin Mintages", - "message": "Euro Coin Mintages", - "translation": "" - }, - { - "id": "Here you’ll be able to view all the known mintages for all coins. You’ll also be able to filter on country, denomination, etc. If you have any mintage data that’s missing from our site, feel free to contact us.", - "message": "Here you’ll be able to view all the known mintages for all coins. You’ll also be able to filter on country, denomination, etc. If you have any mintage data that’s missing from our site, feel free to contact us.", - "translation": "" - }, - { - "id": "Country", - "message": "Country", - "translation": "" - }, - { - "id": "Euro Coins", - "message": "Euro Coins", - "translation": "" - }, - { - "id": "On this section of the site you can find everything there is to know about the coins of the Eurozone. For the latest news on coin- and design releases, check out the {NewsLinkStart}news{LinkEnd} tab!", - "message": "On this section of the site you can find everything there is to know about the coins of the Eurozone. For the latest news on coin- and design releases, check out the {NewsLinkStart}news{LinkEnd} tab!", - "translation": "", - "placeholders": [ - { - "id": "NewsLinkStart", - "string": "%[1]s", - "type": "string", - "underlyingType": "string", - "argNum": 1, - "expr": "newsLinkStart" - }, - { - "id": "LinkEnd", - "string": "%[2]s", - "type": "string", - "underlyingType": "string", - "argNum": 2, - "expr": "linkEnd" - } - ] - }, - { - "id": "Designs", - "message": "Designs", - "translation": "" - }, - { - "id": "View the 600+ different Euro-coin designs!", - "message": "View the 600+ different Euro-coin designs!", - "translation": "" - }, - { - "id": "Mintages", - "message": "Mintages", - "translation": "" - }, - { - "id": "View the mintage figures of all the Euro coins!", - "message": "View the mintage figures of all the Euro coins!", - "translation": "" - }, - { - "id": "Varieties", - "message": "Varieties", - "translation": "" - }, - { - "id": "View all the known Euro varieties!", - "message": "View all the known Euro varieties!", - "translation": "" - }, - { - "id": "Select Your Language", - "message": "Select Your Language", - "translation": "" - }, - { - "id": "Select your preferred language to use on the site.", - "message": "Select your preferred language to use on the site.", - "translation": "" - }, - { - "id": "Eurozone Languages", - "message": "Eurozone Languages", - "translation": "" - }, - { - "id": "Other Languages", - "message": "Other Languages", - "translation": "" - }, - { - "id": "Home", - "message": "Home", - "translation": "" - }, - { - "id": "News", - "message": "News", - "translation": "" - }, - { - "id": "Coin Collecting", - "message": "Coin Collecting", - "translation": "" - }, - { - "id": "Coins", - "message": "Coins", - "translation": "" - }, - { - "id": "Banknotes", - "message": "Banknotes", - "translation": "" - }, - { - "id": "Jargon", - "message": "Jargon", - "translation": "" - }, - { - "id": "Discord", - "message": "Discord", - "translation": "" - }, - { - "id": "About", - "message": "About", - "translation": "" - }, - { - "id": "Language", - "message": "Language", - "translation": "" - }, - { - "id": "The Euro Cash Compendium", - "message": "The Euro Cash Compendium", - "translation": "" - }, - { - "id": "United in", - "message": "United in", - "translation": "" - }, - { - "id": "diversity", - "message": "diversity", - "translation": "" - }, - { - "id": "cash", - "message": "cash", - "translation": "" - }, - { - "id": "Welcome to the Euro Cash Compendium. This sites aims to be a resource for you to discover everything there is to know about the coins and banknotes of the Euro, a currency that spans 26 countries and 350 million people. We also have dedicated sections of the site for collectors.", - "message": "Welcome to the Euro Cash Compendium. This sites aims to be a resource for you to discover everything there is to know about the coins and banknotes of the Euro, a currency that spans 26 countries and 350 million people. We also have dedicated sections of the site for collectors.", - "translation": "" - } - ] -} \ No newline at end of file diff --git a/i18n/locales/el/messages.gotext.json b/i18n/locales/el/messages.gotext.json deleted file mode 100644 index dad7af6..0000000 --- a/i18n/locales/el/messages.gotext.json +++ /dev/null @@ -1,434 +0,0 @@ -{ - "language": "el", - "messages": [ - { - "id": "Page not found", - "message": "Page not found", - "translation": "" - }, - { - "id": "About Us", - "message": "About Us", - "translation": "" - }, - { - "id": "Open Source", - "message": "Open Source", - "translation": "" - }, - { - "id": "This website is an open project, and a collaboration between developers, translators, and researchers. All source code, data, images, and more for the website are open source and can be found {RepoLinkStart}here{LinkEnd}. This site is licensed under the BSD 0-Clause license giving you the full freedom to do whatever you would like with any of the content on this site.", - "message": "This website is an open project, and a collaboration between developers, translators, and researchers. All source code, data, images, and more for the website are open source and can be found {RepoLinkStart}here{LinkEnd}. This site is licensed under the BSD 0-Clause license giving you the full freedom to do whatever you would like with any of the content on this site.", - "translation": "", - "placeholders": [ - { - "id": "RepoLinkStart", - "string": "%[1]s", - "type": "string", - "underlyingType": "string", - "argNum": 1, - "expr": "repoLinkStart" - }, - { - "id": "LinkEnd", - "string": "%[2]s", - "type": "string", - "underlyingType": "string", - "argNum": 2, - "expr": "linkEnd" - } - ] - }, - { - "id": "Contact Us", - "message": "Contact Us", - "translation": "" - }, - { - "id": "While we try to stay as up-to-date as possible and to fact check our information, it is always possible that we get something wrong, lack a translation, or are missing some piece of data you may have. In such a case don’t hesitate to contact us; we’ll try to get the site updated or fixed as soon as possible. You are always free to contribute via a git patch if you are more technically included, but if not you can always send an email to {ContactEmail} or contact ‘@onetruemangoman’ on Discord.", - "message": "While we try to stay as up-to-date as possible and to fact check our information, it is always possible that we get something wrong, lack a translation, or are missing some piece of data you may have. In such a case don’t hesitate to contact us; we’ll try to get the site updated or fixed as soon as possible. You are always free to contribute via a git patch if you are more technically included, but if not you can always send an email to {ContactEmail} or contact ‘@onetruemangoman’ on Discord.", - "translation": "", - "placeholders": [ - { - "id": "ContactEmail", - "string": "%[1]s", - "type": "string", - "underlyingType": "string", - "argNum": 1, - "expr": "contactEmail" - } - ] - }, - { - "id": "Special Thanks", - "message": "Special Thanks", - "translation": "" - }, - { - "id": "Development", - "message": "Development", - "translation": "" - }, - { - "id": "Research", - "message": "Research", - "translation": "" - }, - { - "id": "Translations", - "message": "Translations", - "translation": "" - }, - { - "id": "British- \u0026 American English", - "message": "British- \u0026 American English", - "translation": "" - }, - { - "id": "Icelandic", - "message": "Icelandic", - "translation": "" - }, - { - "id": "Andorra", - "message": "Andorra", - "translation": "Ανδόρα" - }, - { - "id": "Austria", - "message": "Austria", - "translation": "Αυστρία" - }, - { - "id": "Belgium", - "message": "Belgium", - "translation": "Βέλγιο" - }, - { - "id": "Cyprus", - "message": "Cyprus", - "translation": "Κύπρος" - }, - { - "id": "Germany", - "message": "Germany", - "translation": "Γερμανία" - }, - { - "id": "Estonia", - "message": "Estonia", - "translation": "Εσθονία" - }, - { - "id": "Spain", - "message": "Spain", - "translation": "Ισπανία" - }, - { - "id": "Finland", - "message": "Finland", - "translation": "Φινλανδία" - }, - { - "id": "France", - "message": "France", - "translation": "Γαλλία" - }, - { - "id": "Greece", - "message": "Greece", - "translation": "Ελλάδα" - }, - { - "id": "Croatia", - "message": "Croatia", - "translation": "Κροατία" - }, - { - "id": "Ireland", - "message": "Ireland", - "translation": "Ιρλανδία" - }, - { - "id": "Italy", - "message": "Italy", - "translation": "Ιταλία" - }, - { - "id": "Lithuania", - "message": "Lithuania", - "translation": "Λιθουανία" - }, - { - "id": "Luxembourg", - "message": "Luxembourg", - "translation": "Λουξεμβούργο" - }, - { - "id": "Latvia", - "message": "Latvia", - "translation": "Λετονία" - }, - { - "id": "Monaco", - "message": "Monaco", - "translation": "Μονακό" - }, - { - "id": "Malta", - "message": "Malta", - "translation": "Μάλτα" - }, - { - "id": "Netherlands", - "message": "Netherlands", - "translation": "Ολλανδία" - }, - { - "id": "Portugal", - "message": "Portugal", - "translation": "Πορτογαλία" - }, - { - "id": "Slovenia", - "message": "Slovenia", - "translation": "Σλοβενία" - }, - { - "id": "Slovakia", - "message": "Slovakia", - "translation": "Σλοβακία" - }, - { - "id": "San Marino", - "message": "San Marino", - "translation": "Σαν Μαρίνο" - }, - { - "id": "Vatican City", - "message": "Vatican City", - "translation": "Βατικανό" - }, - { - "id": "Found a mistake or want to contribute missing information?", - "message": "Found a mistake or want to contribute missing information?", - "translation": "" - }, - { - "id": "Feel free to contact us!", - "message": "Feel free to contact us!", - "translation": "" - }, - { - "id": "Dutch Euro Coin Designs", - "message": "Dutch Euro Coin Designs", - "translation": "" - }, - { - "id": "From the years 1999–2013 all Dutch euro coins featured the portrait of Queen Beatrix of the Netherlands. After her abdication from the throne in 2013 the designs of all denominations were changed to feature the portrait of the new King Willem-Alexander. After her abdication the direction in which the monarchs portrait faced was flipped; a tradition dating back to the earliest coins of the Kingdom of the Netherlands.", - "message": "From the years 1999–2013 all Dutch euro coins featured the portrait of Queen Beatrix of the Netherlands. After her abdication from the throne in 2013 the designs of all denominations were changed to feature the portrait of the new King Willem-Alexander. After her abdication the direction in which the monarchs portrait faced was flipped; a tradition dating back to the earliest coins of the Kingdom of the Netherlands.", - "translation": "" - }, - { - "id": "Coins featuring both monarchs contain text reading ‘BEATRIX KONINGIN DER NEDERLANDEN’ (‘BEATRIX QUEEN OF THE NETHERLANDS’) and ‘Willem-Alexander Koning der Nederlanden’ (‘Willem-Alexander King of the Netherlands’) respectively.", - "message": "Coins featuring both monarchs contain text reading ‘BEATRIX KONINGIN DER NEDERLANDEN’ (‘BEATRIX QUEEN OF THE NETHERLANDS’) and ‘Willem-Alexander Koning der Nederlanden’ (‘Willem-Alexander King of the Netherlands’) respectively.", - "translation": "" - }, - { - "id": "The €1 and €2 coins featuring King Willem-Alexander were minted with a much lower relief than most euro coins of the same denomination. As a result it is not uncommon for these coins to appear worn after little use in circulation.", - "message": "The €1 and €2 coins featuring King Willem-Alexander were minted with a much lower relief than most euro coins of the same denomination. As a result it is not uncommon for these coins to appear worn after little use in circulation.", - "translation": "" - }, - { - "id": "Euro Coin Designs", - "message": "Euro Coin Designs", - "translation": "" - }, - { - "id": "Here you’ll be able to view all the coin designs for each country in the Eurozone. This section of the site doesn’t include minor varieties such as different mintmarks or errors; those are on the {VarietiesLinkStart}varieties{LinkEnd} page.", - "message": "Here you’ll be able to view all the coin designs for each country in the Eurozone. This section of the site doesn’t include minor varieties such as different mintmarks or errors; those are on the {VarietiesLinkStart}varieties{LinkEnd} page.", - "translation": "", - "placeholders": [ - { - "id": "VarietiesLinkStart", - "string": "%[1]s", - "type": "string", - "underlyingType": "string", - "argNum": 1, - "expr": "varietiesLinkStart" - }, - { - "id": "LinkEnd", - "string": "%[2]s", - "type": "string", - "underlyingType": "string", - "argNum": 2, - "expr": "linkEnd" - } - ] - }, - { - "id": "Euro Coin Mintages", - "message": "Euro Coin Mintages", - "translation": "" - }, - { - "id": "Here you’ll be able to view all the known mintages for all coins. You’ll also be able to filter on country, denomination, etc. If you have any mintage data that’s missing from our site, feel free to contact us.", - "message": "Here you’ll be able to view all the known mintages for all coins. You’ll also be able to filter on country, denomination, etc. If you have any mintage data that’s missing from our site, feel free to contact us.", - "translation": "" - }, - { - "id": "Country", - "message": "Country", - "translation": "" - }, - { - "id": "Euro Coins", - "message": "Euro Coins", - "translation": "" - }, - { - "id": "On this section of the site you can find everything there is to know about the coins of the Eurozone. For the latest news on coin- and design releases, check out the {NewsLinkStart}news{LinkEnd} tab!", - "message": "On this section of the site you can find everything there is to know about the coins of the Eurozone. For the latest news on coin- and design releases, check out the {NewsLinkStart}news{LinkEnd} tab!", - "translation": "", - "placeholders": [ - { - "id": "NewsLinkStart", - "string": "%[1]s", - "type": "string", - "underlyingType": "string", - "argNum": 1, - "expr": "newsLinkStart" - }, - { - "id": "LinkEnd", - "string": "%[2]s", - "type": "string", - "underlyingType": "string", - "argNum": 2, - "expr": "linkEnd" - } - ] - }, - { - "id": "Designs", - "message": "Designs", - "translation": "" - }, - { - "id": "View the 600+ different Euro-coin designs!", - "message": "View the 600+ different Euro-coin designs!", - "translation": "" - }, - { - "id": "Mintages", - "message": "Mintages", - "translation": "" - }, - { - "id": "View the mintage figures of all the Euro coins!", - "message": "View the mintage figures of all the Euro coins!", - "translation": "" - }, - { - "id": "Varieties", - "message": "Varieties", - "translation": "" - }, - { - "id": "View all the known Euro varieties!", - "message": "View all the known Euro varieties!", - "translation": "" - }, - { - "id": "Select Your Language", - "message": "Select Your Language", - "translation": "" - }, - { - "id": "Select your preferred language to use on the site.", - "message": "Select your preferred language to use on the site.", - "translation": "" - }, - { - "id": "Eurozone Languages", - "message": "Eurozone Languages", - "translation": "" - }, - { - "id": "Other Languages", - "message": "Other Languages", - "translation": "" - }, - { - "id": "Home", - "message": "Home", - "translation": "" - }, - { - "id": "News", - "message": "News", - "translation": "" - }, - { - "id": "Coin Collecting", - "message": "Coin Collecting", - "translation": "" - }, - { - "id": "Coins", - "message": "Coins", - "translation": "" - }, - { - "id": "Banknotes", - "message": "Banknotes", - "translation": "" - }, - { - "id": "Jargon", - "message": "Jargon", - "translation": "" - }, - { - "id": "Discord", - "message": "Discord", - "translation": "" - }, - { - "id": "About", - "message": "About", - "translation": "" - }, - { - "id": "Language", - "message": "Language", - "translation": "" - }, - { - "id": "The Euro Cash Compendium", - "message": "The Euro Cash Compendium", - "translation": "" - }, - { - "id": "United in", - "message": "United in", - "translation": "" - }, - { - "id": "diversity", - "message": "diversity", - "translation": "" - }, - { - "id": "cash", - "message": "cash", - "translation": "" - }, - { - "id": "Welcome to the Euro Cash Compendium. This sites aims to be a resource for you to discover everything there is to know about the coins and banknotes of the Euro, a currency that spans 26 countries and 350 million people. We also have dedicated sections of the site for collectors.", - "message": "Welcome to the Euro Cash Compendium. This sites aims to be a resource for you to discover everything there is to know about the coins and banknotes of the Euro, a currency that spans 26 countries and 350 million people. We also have dedicated sections of the site for collectors.", - "translation": "" - } - ] -} \ No newline at end of file diff --git a/i18n/locales/en/messages.gotext.json b/i18n/locales/en/messages.gotext.json deleted file mode 100644 index e739b20..0000000 --- a/i18n/locales/en/messages.gotext.json +++ /dev/null @@ -1,580 +0,0 @@ -{ - "language": "en", - "messages": [ - { - "id": "Page not found", - "message": "Page not found", - "translation": "Page not found", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "About Us", - "message": "About Us", - "translation": "About Us", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Open Source", - "message": "Open Source", - "translation": "Open Source", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "This website is an open project, and a collaboration between developers, translators, and researchers. All source code, data, images, and more for the website are open source and can be found {RepoLinkStart}here{LinkEnd}. This site is licensed under the BSD 0-Clause license giving you the full freedom to do whatever you would like with any of the content on this site.", - "message": "This website is an open project, and a collaboration between developers, translators, and researchers. All source code, data, images, and more for the website are open source and can be found {RepoLinkStart}here{LinkEnd}. This site is licensed under the BSD 0-Clause license giving you the full freedom to do whatever you would like with any of the content on this site.", - "translation": "This website is an open project, and a collaboration between developers, translators, and researchers. All source code, data, images, and more for the website are open source and can be found {RepoLinkStart}here{LinkEnd}. This site is licensed under the BSD 0-Clause license giving you the full freedom to do whatever you would like with any of the content on this site.", - "translatorComment": "Copied from source.", - "placeholders": [ - { - "id": "RepoLinkStart", - "string": "%[1]s", - "type": "string", - "underlyingType": "string", - "argNum": 1, - "expr": "repoLinkStart" - }, - { - "id": "LinkEnd", - "string": "%[2]s", - "type": "string", - "underlyingType": "string", - "argNum": 2, - "expr": "linkEnd" - } - ], - "fuzzy": true - }, - { - "id": "Contact Us", - "message": "Contact Us", - "translation": "Contact Us", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "While we try to stay as up-to-date as possible and to fact check our information, it is always possible that we get something wrong, lack a translation, or are missing some piece of data you may have. In such a case don’t hesitate to contact us; we’ll try to get the site updated or fixed as soon as possible. You are always free to contribute via a git patch if you are more technically included, but if not you can always send an email to {ContactEmail} or contact ‘@onetruemangoman’ on Discord.", - "message": "While we try to stay as up-to-date as possible and to fact check our information, it is always possible that we get something wrong, lack a translation, or are missing some piece of data you may have. In such a case don’t hesitate to contact us; we’ll try to get the site updated or fixed as soon as possible. You are always free to contribute via a git patch if you are more technically included, but if not you can always send an email to {ContactEmail} or contact ‘@onetruemangoman’ on Discord.", - "translation": "While we try to stay as up-to-date as possible and to fact check our information, it is always possible that we get something wrong, lack a translation, or are missing some piece of data you may have. In such a case don’t hesitate to contact us; we’ll try to get the site updated or fixed as soon as possible. You are always free to contribute via a git patch if you are more technically included, but if not you can always send an email to {ContactEmail} or contact ‘@onetruemangoman’ on Discord.", - "translatorComment": "Copied from source.", - "placeholders": [ - { - "id": "ContactEmail", - "string": "%[1]s", - "type": "string", - "underlyingType": "string", - "argNum": 1, - "expr": "contactEmail" - } - ], - "fuzzy": true - }, - { - "id": "Special Thanks", - "message": "Special Thanks", - "translation": "Special Thanks", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Development", - "message": "Development", - "translation": "Development", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Research", - "message": "Research", - "translation": "Research", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Translations", - "message": "Translations", - "translation": "Translations", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "British- \u0026 American English", - "message": "British- \u0026 American English", - "translation": "British- \u0026 American English", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Icelandic", - "message": "Icelandic", - "translation": "Icelandic", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Andorra", - "message": "Andorra", - "translation": "Andorra", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Austria", - "message": "Austria", - "translation": "Austria", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Belgium", - "message": "Belgium", - "translation": "Belgium", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Cyprus", - "message": "Cyprus", - "translation": "Cyprus", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Germany", - "message": "Germany", - "translation": "Germany", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Estonia", - "message": "Estonia", - "translation": "Estonia", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Spain", - "message": "Spain", - "translation": "Spain", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Finland", - "message": "Finland", - "translation": "Finland", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "France", - "message": "France", - "translation": "France", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Greece", - "message": "Greece", - "translation": "Greece", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Croatia", - "message": "Croatia", - "translation": "Croatia", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Ireland", - "message": "Ireland", - "translation": "Ireland", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Italy", - "message": "Italy", - "translation": "Italy", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Lithuania", - "message": "Lithuania", - "translation": "Lithuania", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Luxembourg", - "message": "Luxembourg", - "translation": "Luxembourg", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Latvia", - "message": "Latvia", - "translation": "Latvia", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Monaco", - "message": "Monaco", - "translation": "Monaco", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Malta", - "message": "Malta", - "translation": "Malta", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Netherlands", - "message": "Netherlands", - "translation": "Netherlands", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Portugal", - "message": "Portugal", - "translation": "Portugal", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Slovenia", - "message": "Slovenia", - "translation": "Slovenia", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Slovakia", - "message": "Slovakia", - "translation": "Slovakia", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "San Marino", - "message": "San Marino", - "translation": "San Marino", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Vatican City", - "message": "Vatican City", - "translation": "Vatican City", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Found a mistake or want to contribute missing information?", - "message": "Found a mistake or want to contribute missing information?", - "translation": "Found a mistake or want to contribute missing information?", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Feel free to contact us!", - "message": "Feel free to contact us!", - "translation": "Feel free to contact us!", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Dutch Euro Coin Designs", - "message": "Dutch Euro Coin Designs", - "translation": "Dutch Euro Coin Designs", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "From the years 1999–2013 all Dutch euro coins featured the portrait of Queen Beatrix of the Netherlands. After her abdication from the throne in 2013 the designs of all denominations were changed to feature the portrait of the new King Willem-Alexander. After her abdication the direction in which the monarchs portrait faced was flipped; a tradition dating back to the earliest coins of the Kingdom of the Netherlands.", - "message": "From the years 1999–2013 all Dutch euro coins featured the portrait of Queen Beatrix of the Netherlands. After her abdication from the throne in 2013 the designs of all denominations were changed to feature the portrait of the new King Willem-Alexander. After her abdication the direction in which the monarchs portrait faced was flipped; a tradition dating back to the earliest coins of the Kingdom of the Netherlands.", - "translation": "From the years 1999–2013 all Dutch euro coins featured the portrait of Queen Beatrix of the Netherlands. After her abdication from the throne in 2013 the designs of all denominations were changed to feature the portrait of the new King Willem-Alexander. After her abdication the direction in which the monarchs portrait faced was flipped; a tradition dating back to the earliest coins of the Kingdom of the Netherlands.", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Coins featuring both monarchs contain text reading ‘BEATRIX KONINGIN DER NEDERLANDEN’ (‘BEATRIX QUEEN OF THE NETHERLANDS’) and ‘Willem-Alexander Koning der Nederlanden’ (‘Willem-Alexander King of the Netherlands’) respectively.", - "message": "Coins featuring both monarchs contain text reading ‘BEATRIX KONINGIN DER NEDERLANDEN’ (‘BEATRIX QUEEN OF THE NETHERLANDS’) and ‘Willem-Alexander Koning der Nederlanden’ (‘Willem-Alexander King of the Netherlands’) respectively.", - "translation": "Coins featuring both monarchs contain text reading ‘BEATRIX KONINGIN DER NEDERLANDEN’ (‘BEATRIX QUEEN OF THE NETHERLANDS’) and ‘Willem-Alexander Koning der Nederlanden’ (‘Willem-Alexander King of the Netherlands’) respectively.", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "The €1 and €2 coins featuring King Willem-Alexander were minted with a much lower relief than most euro coins of the same denomination. As a result it is not uncommon for these coins to appear worn after little use in circulation.", - "message": "The €1 and €2 coins featuring King Willem-Alexander were minted with a much lower relief than most euro coins of the same denomination. As a result it is not uncommon for these coins to appear worn after little use in circulation.", - "translation": "The €1 and €2 coins featuring King Willem-Alexander were minted with a much lower relief than most euro coins of the same denomination. As a result it is not uncommon for these coins to appear worn after little use in circulation.", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Euro Coin Designs", - "message": "Euro Coin Designs", - "translation": "Euro Coin Designs", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Here you’ll be able to view all the coin designs for each country in the Eurozone. This section of the site doesn’t include minor varieties such as different mintmarks or errors; those are on the {VarietiesLinkStart}varieties{LinkEnd} page.", - "message": "Here you’ll be able to view all the coin designs for each country in the Eurozone. This section of the site doesn’t include minor varieties such as different mintmarks or errors; those are on the {VarietiesLinkStart}varieties{LinkEnd} page.", - "translation": "Here you’ll be able to view all the coin designs for each country in the Eurozone. This section of the site doesn’t include minor varieties such as different mintmarks or errors; those are on the {VarietiesLinkStart}varieties{LinkEnd} page.", - "translatorComment": "Copied from source.", - "placeholders": [ - { - "id": "VarietiesLinkStart", - "string": "%[1]s", - "type": "string", - "underlyingType": "string", - "argNum": 1, - "expr": "varietiesLinkStart" - }, - { - "id": "LinkEnd", - "string": "%[2]s", - "type": "string", - "underlyingType": "string", - "argNum": 2, - "expr": "linkEnd" - } - ], - "fuzzy": true - }, - { - "id": "Euro Coin Mintages", - "message": "Euro Coin Mintages", - "translation": "Euro Coin Mintages", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Here you’ll be able to view all the known mintages for all coins. You’ll also be able to filter on country, denomination, etc. If you have any mintage data that’s missing from our site, feel free to contact us.", - "message": "Here you’ll be able to view all the known mintages for all coins. You’ll also be able to filter on country, denomination, etc. If you have any mintage data that’s missing from our site, feel free to contact us.", - "translation": "Here you’ll be able to view all the known mintages for all coins. You’ll also be able to filter on country, denomination, etc. If you have any mintage data that’s missing from our site, feel free to contact us.", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Country", - "message": "Country", - "translation": "Country", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Euro Coins", - "message": "Euro Coins", - "translation": "Euro Coins", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "On this section of the site you can find everything there is to know about the coins of the Eurozone. For the latest news on coin- and design releases, check out the {NewsLinkStart}news{LinkEnd} tab!", - "message": "On this section of the site you can find everything there is to know about the coins of the Eurozone. For the latest news on coin- and design releases, check out the {NewsLinkStart}news{LinkEnd} tab!", - "translation": "On this section of the site you can find everything there is to know about the coins of the Eurozone. For the latest news on coin- and design releases, check out the {NewsLinkStart}news{LinkEnd} tab!", - "translatorComment": "Copied from source.", - "placeholders": [ - { - "id": "NewsLinkStart", - "string": "%[1]s", - "type": "string", - "underlyingType": "string", - "argNum": 1, - "expr": "newsLinkStart" - }, - { - "id": "LinkEnd", - "string": "%[2]s", - "type": "string", - "underlyingType": "string", - "argNum": 2, - "expr": "linkEnd" - } - ], - "fuzzy": true - }, - { - "id": "Designs", - "message": "Designs", - "translation": "Designs", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "View the 600+ different Euro-coin designs!", - "message": "View the 600+ different Euro-coin designs!", - "translation": "View the 600+ different Euro-coin designs!", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Mintages", - "message": "Mintages", - "translation": "Mintages", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "View the mintage figures of all the Euro coins!", - "message": "View the mintage figures of all the Euro coins!", - "translation": "View the mintage figures of all the Euro coins!", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Varieties", - "message": "Varieties", - "translation": "Varieties", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "View all the known Euro varieties!", - "message": "View all the known Euro varieties!", - "translation": "View all the known Euro varieties!", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Select Your Language", - "message": "Select Your Language", - "translation": "Select Your Language", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Select your preferred language to use on the site.", - "message": "Select your preferred language to use on the site.", - "translation": "Select your preferred language to use on the site.", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Eurozone Languages", - "message": "Eurozone Languages", - "translation": "Eurozone Languages", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Other Languages", - "message": "Other Languages", - "translation": "Other Languages", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Home", - "message": "Home", - "translation": "Home", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "News", - "message": "News", - "translation": "News", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Coin Collecting", - "message": "Coin Collecting", - "translation": "Coin Collecting", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Coins", - "message": "Coins", - "translation": "Coins", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Banknotes", - "message": "Banknotes", - "translation": "Banknotes", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Jargon", - "message": "Jargon", - "translation": "Jargon", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Discord", - "message": "Discord", - "translation": "Discord", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "About", - "message": "About", - "translation": "About", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Language", - "message": "Language", - "translation": "Language", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "The Euro Cash Compendium", - "message": "The Euro Cash Compendium", - "translation": "The Euro Cash Compendium", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "United in", - "message": "United in", - "translation": "United in", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "diversity", - "message": "diversity", - "translation": "diversity", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "cash", - "message": "cash", - "translation": "cash", - "translatorComment": "Copied from source.", - "fuzzy": true - }, - { - "id": "Welcome to the Euro Cash Compendium. This sites aims to be a resource for you to discover everything there is to know about the coins and banknotes of the Euro, a currency that spans 26 countries and 350 million people. We also have dedicated sections of the site for collectors.", - "message": "Welcome to the Euro Cash Compendium. This sites aims to be a resource for you to discover everything there is to know about the coins and banknotes of the Euro, a currency that spans 26 countries and 350 million people. We also have dedicated sections of the site for collectors.", - "translation": "Welcome to the Euro Cash Compendium. This sites aims to be a resource for you to discover everything there is to know about the coins and banknotes of the Euro, a currency that spans 26 countries and 350 million people. We also have dedicated sections of the site for collectors.", - "translatorComment": "Copied from source.", - "fuzzy": true - } - ] -} \ No newline at end of file diff --git a/i18n/locales/nl/messages.gotext.json b/i18n/locales/nl/messages.gotext.json deleted file mode 100644 index 4d5e53b..0000000 --- a/i18n/locales/nl/messages.gotext.json +++ /dev/null @@ -1,434 +0,0 @@ -{ - "language": "nl", - "messages": [ - { - "id": "Page not found", - "message": "Page not found", - "translation": "" - }, - { - "id": "About Us", - "message": "About Us", - "translation": "" - }, - { - "id": "Open Source", - "message": "Open Source", - "translation": "" - }, - { - "id": "This website is an open project, and a collaboration between developers, translators, and researchers. All source code, data, images, and more for the website are open source and can be found {RepoLinkStart}here{LinkEnd}. This site is licensed under the BSD 0-Clause license giving you the full freedom to do whatever you would like with any of the content on this site.", - "message": "This website is an open project, and a collaboration between developers, translators, and researchers. All source code, data, images, and more for the website are open source and can be found {RepoLinkStart}here{LinkEnd}. This site is licensed under the BSD 0-Clause license giving you the full freedom to do whatever you would like with any of the content on this site.", - "translation": "", - "placeholders": [ - { - "id": "RepoLinkStart", - "string": "%[1]s", - "type": "string", - "underlyingType": "string", - "argNum": 1, - "expr": "repoLinkStart" - }, - { - "id": "LinkEnd", - "string": "%[2]s", - "type": "string", - "underlyingType": "string", - "argNum": 2, - "expr": "linkEnd" - } - ] - }, - { - "id": "Contact Us", - "message": "Contact Us", - "translation": "" - }, - { - "id": "While we try to stay as up-to-date as possible and to fact check our information, it is always possible that we get something wrong, lack a translation, or are missing some piece of data you may have. In such a case don’t hesitate to contact us; we’ll try to get the site updated or fixed as soon as possible. You are always free to contribute via a git patch if you are more technically included, but if not you can always send an email to {ContactEmail} or contact ‘@onetruemangoman’ on Discord.", - "message": "While we try to stay as up-to-date as possible and to fact check our information, it is always possible that we get something wrong, lack a translation, or are missing some piece of data you may have. In such a case don’t hesitate to contact us; we’ll try to get the site updated or fixed as soon as possible. You are always free to contribute via a git patch if you are more technically included, but if not you can always send an email to {ContactEmail} or contact ‘@onetruemangoman’ on Discord.", - "translation": "", - "placeholders": [ - { - "id": "ContactEmail", - "string": "%[1]s", - "type": "string", - "underlyingType": "string", - "argNum": 1, - "expr": "contactEmail" - } - ] - }, - { - "id": "Special Thanks", - "message": "Special Thanks", - "translation": "" - }, - { - "id": "Development", - "message": "Development", - "translation": "" - }, - { - "id": "Research", - "message": "Research", - "translation": "" - }, - { - "id": "Translations", - "message": "Translations", - "translation": "" - }, - { - "id": "British- \u0026 American English", - "message": "British- \u0026 American English", - "translation": "" - }, - { - "id": "Icelandic", - "message": "Icelandic", - "translation": "" - }, - { - "id": "Andorra", - "message": "Andorra", - "translation": "Andorra" - }, - { - "id": "Austria", - "message": "Austria", - "translation": "Oostenrijk" - }, - { - "id": "Belgium", - "message": "Belgium", - "translation": "België" - }, - { - "id": "Cyprus", - "message": "Cyprus", - "translation": "Cyprus" - }, - { - "id": "Germany", - "message": "Germany", - "translation": "Duitsland" - }, - { - "id": "Estonia", - "message": "Estonia", - "translation": "Estland" - }, - { - "id": "Spain", - "message": "Spain", - "translation": "Spanje" - }, - { - "id": "Finland", - "message": "Finland", - "translation": "Finland" - }, - { - "id": "France", - "message": "France", - "translation": "Frankrijk" - }, - { - "id": "Greece", - "message": "Greece", - "translation": "Griekenland" - }, - { - "id": "Croatia", - "message": "Croatia", - "translation": "Kroatië" - }, - { - "id": "Ireland", - "message": "Ireland", - "translation": "Ierland" - }, - { - "id": "Italy", - "message": "Italy", - "translation": "Italië" - }, - { - "id": "Lithuania", - "message": "Lithuania", - "translation": "Litouwen" - }, - { - "id": "Luxembourg", - "message": "Luxembourg", - "translation": "Luxemburg" - }, - { - "id": "Latvia", - "message": "Latvia", - "translation": "Letland" - }, - { - "id": "Monaco", - "message": "Monaco", - "translation": "Monaco" - }, - { - "id": "Malta", - "message": "Malta", - "translation": "Malta" - }, - { - "id": "Netherlands", - "message": "Netherlands", - "translation": "Nederland" - }, - { - "id": "Portugal", - "message": "Portugal", - "translation": "Portugal" - }, - { - "id": "Slovenia", - "message": "Slovenia", - "translation": "Slovenië" - }, - { - "id": "Slovakia", - "message": "Slovakia", - "translation": "Slowakije" - }, - { - "id": "San Marino", - "message": "San Marino", - "translation": "San Marino" - }, - { - "id": "Vatican City", - "message": "Vatican City", - "translation": "Vaticaanstad" - }, - { - "id": "Found a mistake or want to contribute missing information?", - "message": "Found a mistake or want to contribute missing information?", - "translation": "" - }, - { - "id": "Feel free to contact us!", - "message": "Feel free to contact us!", - "translation": "" - }, - { - "id": "Dutch Euro Coin Designs", - "message": "Dutch Euro Coin Designs", - "translation": "" - }, - { - "id": "From the years 1999–2013 all Dutch euro coins featured the portrait of Queen Beatrix of the Netherlands. After her abdication from the throne in 2013 the designs of all denominations were changed to feature the portrait of the new King Willem-Alexander. After her abdication the direction in which the monarchs portrait faced was flipped; a tradition dating back to the earliest coins of the Kingdom of the Netherlands.", - "message": "From the years 1999–2013 all Dutch euro coins featured the portrait of Queen Beatrix of the Netherlands. After her abdication from the throne in 2013 the designs of all denominations were changed to feature the portrait of the new King Willem-Alexander. After her abdication the direction in which the monarchs portrait faced was flipped; a tradition dating back to the earliest coins of the Kingdom of the Netherlands.", - "translation": "" - }, - { - "id": "Coins featuring both monarchs contain text reading ‘BEATRIX KONINGIN DER NEDERLANDEN’ (‘BEATRIX QUEEN OF THE NETHERLANDS’) and ‘Willem-Alexander Koning der Nederlanden’ (‘Willem-Alexander King of the Netherlands’) respectively.", - "message": "Coins featuring both monarchs contain text reading ‘BEATRIX KONINGIN DER NEDERLANDEN’ (‘BEATRIX QUEEN OF THE NETHERLANDS’) and ‘Willem-Alexander Koning der Nederlanden’ (‘Willem-Alexander King of the Netherlands’) respectively.", - "translation": "" - }, - { - "id": "The €1 and €2 coins featuring King Willem-Alexander were minted with a much lower relief than most euro coins of the same denomination. As a result it is not uncommon for these coins to appear worn after little use in circulation.", - "message": "The €1 and €2 coins featuring King Willem-Alexander were minted with a much lower relief than most euro coins of the same denomination. As a result it is not uncommon for these coins to appear worn after little use in circulation.", - "translation": "" - }, - { - "id": "Euro Coin Designs", - "message": "Euro Coin Designs", - "translation": "" - }, - { - "id": "Here you’ll be able to view all the coin designs for each country in the Eurozone. This section of the site doesn’t include minor varieties such as different mintmarks or errors; those are on the {VarietiesLinkStart}varieties{LinkEnd} page.", - "message": "Here you’ll be able to view all the coin designs for each country in the Eurozone. This section of the site doesn’t include minor varieties such as different mintmarks or errors; those are on the {VarietiesLinkStart}varieties{LinkEnd} page.", - "translation": "", - "placeholders": [ - { - "id": "VarietiesLinkStart", - "string": "%[1]s", - "type": "string", - "underlyingType": "string", - "argNum": 1, - "expr": "varietiesLinkStart" - }, - { - "id": "LinkEnd", - "string": "%[2]s", - "type": "string", - "underlyingType": "string", - "argNum": 2, - "expr": "linkEnd" - } - ] - }, - { - "id": "Euro Coin Mintages", - "message": "Euro Coin Mintages", - "translation": "" - }, - { - "id": "Here you’ll be able to view all the known mintages for all coins. You’ll also be able to filter on country, denomination, etc. If you have any mintage data that’s missing from our site, feel free to contact us.", - "message": "Here you’ll be able to view all the known mintages for all coins. You’ll also be able to filter on country, denomination, etc. If you have any mintage data that’s missing from our site, feel free to contact us.", - "translation": "" - }, - { - "id": "Country", - "message": "Country", - "translation": "" - }, - { - "id": "Euro Coins", - "message": "Euro Coins", - "translation": "" - }, - { - "id": "On this section of the site you can find everything there is to know about the coins of the Eurozone. For the latest news on coin- and design releases, check out the {NewsLinkStart}news{LinkEnd} tab!", - "message": "On this section of the site you can find everything there is to know about the coins of the Eurozone. For the latest news on coin- and design releases, check out the {NewsLinkStart}news{LinkEnd} tab!", - "translation": "", - "placeholders": [ - { - "id": "NewsLinkStart", - "string": "%[1]s", - "type": "string", - "underlyingType": "string", - "argNum": 1, - "expr": "newsLinkStart" - }, - { - "id": "LinkEnd", - "string": "%[2]s", - "type": "string", - "underlyingType": "string", - "argNum": 2, - "expr": "linkEnd" - } - ] - }, - { - "id": "Designs", - "message": "Designs", - "translation": "" - }, - { - "id": "View the 600+ different Euro-coin designs!", - "message": "View the 600+ different Euro-coin designs!", - "translation": "" - }, - { - "id": "Mintages", - "message": "Mintages", - "translation": "" - }, - { - "id": "View the mintage figures of all the Euro coins!", - "message": "View the mintage figures of all the Euro coins!", - "translation": "" - }, - { - "id": "Varieties", - "message": "Varieties", - "translation": "" - }, - { - "id": "View all the known Euro varieties!", - "message": "View all the known Euro varieties!", - "translation": "" - }, - { - "id": "Select Your Language", - "message": "Select Your Language", - "translation": "" - }, - { - "id": "Select your preferred language to use on the site.", - "message": "Select your preferred language to use on the site.", - "translation": "" - }, - { - "id": "Eurozone Languages", - "message": "Eurozone Languages", - "translation": "" - }, - { - "id": "Other Languages", - "message": "Other Languages", - "translation": "" - }, - { - "id": "Home", - "message": "Home", - "translation": "" - }, - { - "id": "News", - "message": "News", - "translation": "" - }, - { - "id": "Coin Collecting", - "message": "Coin Collecting", - "translation": "" - }, - { - "id": "Coins", - "message": "Coins", - "translation": "" - }, - { - "id": "Banknotes", - "message": "Banknotes", - "translation": "" - }, - { - "id": "Jargon", - "message": "Jargon", - "translation": "" - }, - { - "id": "Discord", - "message": "Discord", - "translation": "" - }, - { - "id": "About", - "message": "About", - "translation": "" - }, - { - "id": "Language", - "message": "Language", - "translation": "" - }, - { - "id": "The Euro Cash Compendium", - "message": "The Euro Cash Compendium", - "translation": "" - }, - { - "id": "United in", - "message": "United in", - "translation": "" - }, - { - "id": "diversity", - "message": "diversity", - "translation": "" - }, - { - "id": "cash", - "message": "cash", - "translation": "" - }, - { - "id": "Welcome to the Euro Cash Compendium. This sites aims to be a resource for you to discover everything there is to know about the coins and banknotes of the Euro, a currency that spans 26 countries and 350 million people. We also have dedicated sections of the site for collectors.", - "message": "Welcome to the Euro Cash Compendium. This sites aims to be a resource for you to discover everything there is to know about the coins and banknotes of the Euro, a currency that spans 26 countries and 350 million people. We also have dedicated sections of the site for collectors.", - "translation": "" - } - ] -} \ No newline at end of file diff --git a/i18n/printer.go b/i18n/printer.go deleted file mode 100644 index a933622..0000000 --- a/i18n/printer.go +++ /dev/null @@ -1,251 +0,0 @@ -package i18n - -import ( - "fmt" - "strings" - "time" - - "golang.org/x/text/language" - "golang.org/x/text/message" -) - -//go:generate gotext -srclang=en update -out=catalog.go -lang=bg,el,en,nl git.thomasvoss.com/euro-cash.eu - -type Printer struct { - Locale Locale - printer *message.Printer -} - -type Locale struct { - Bcp string - Name string - dateFmt string - moneyFmt string - Eurozone bool - Enabled bool -} - -var ( - Locales = [...]Locale{ - { - Bcp: "ca", - Name: "català", - dateFmt: "2/1/2006", - Eurozone: true, - Enabled: false, - }, - { - Bcp: "de", - Name: "Deutsch", - dateFmt: "2.1.2006", - Eurozone: true, - Enabled: false, - }, - { - Bcp: "el", - Name: "ελληνικά", - dateFmt: "2/1/2006", - Eurozone: true, - Enabled: true, - }, - { - Bcp: "en", - Name: "English", - dateFmt: "02/01/2006", - Eurozone: true, - Enabled: true, - }, - { - Bcp: "es", - Name: "español", - dateFmt: "2/1/2006", - Eurozone: true, - Enabled: false, - }, - { - Bcp: "et", - Name: "eesti", - dateFmt: "2.1.2006", - Eurozone: true, - Enabled: false, - }, - { - Bcp: "fi", - Name: "suomi", - dateFmt: "2.1.2006", - Eurozone: true, - Enabled: false, - }, - { - Bcp: "fr", - Name: "français", - dateFmt: "02/01/2006", - Eurozone: true, - Enabled: false, - }, - { - Bcp: "ga", - Name: "Gaeilge", - dateFmt: "02/01/2006", - Eurozone: true, - Enabled: false, - }, - { - Bcp: "hr", - Name: "hrvatski", - dateFmt: "02. 01. 2006.", - Eurozone: true, - Enabled: false, - }, - { - Bcp: "it", - Name: "italiano", - dateFmt: "02/01/2006", - Eurozone: true, - Enabled: false, - }, - { - Bcp: "lb", - Name: "lëtzebuergesch", - dateFmt: "2.1.2006", - Eurozone: true, - Enabled: false, - }, - { - Bcp: "lt", - Name: "lietuvių", - dateFmt: "2006-01-02", - Eurozone: true, - Enabled: false, - }, - { - Bcp: "lv", - Name: "latviešu", - dateFmt: "2.01.2006.", - Eurozone: true, - Enabled: false, - }, - { - Bcp: "mt", - Name: "Malti", - dateFmt: "2/1/2006", - Eurozone: true, - Enabled: false, - }, - { - Bcp: "nl", - Name: "Nederlands", - dateFmt: "2-1-2006", - Eurozone: true, - Enabled: true, - }, - { - Bcp: "pt", - Name: "português", - dateFmt: "02/01/2006", - Eurozone: true, - Enabled: false, - }, - { - Bcp: "sk", - Name: "slovenčina", - dateFmt: "2. 1. 2006", - Eurozone: true, - Enabled: false, - }, - { - Bcp: "sl", - Name: "slovenščina", - dateFmt: "2. 1. 2006", - Eurozone: true, - Enabled: false, - }, - - /* Non-Eurozone locales */ - { - Bcp: "bg", - Name: "български", - dateFmt: "2.01.2006 г.", - Eurozone: false, - Enabled: true, - }, - { - Bcp: "en-US", - Name: "English (US)", - dateFmt: "1/2/2006", - Eurozone: false, - Enabled: false, - }, - { - Bcp: "ro", - Name: "română", - dateFmt: "02.01.2006", - Eurozone: false, - Enabled: false, - }, - { - Bcp: "uk", - Name: "yкраїнська", - dateFmt: "02.01.2006", - Eurozone: false, - Enabled: false, - }, - } - /* Map of language codes to printers. We do this instead of just - using language.MustParse() directly so that we can easily see if a - language is supported or not. */ - Printers map[string]Printer = make(map[string]Printer, len(Locales)) - DefaultPrinter Printer -) - -func InitPrinters() { - for _, loc := range Locales { - if loc.Enabled { - lang := language.MustParse(loc.Bcp) - Printers[strings.ToLower(loc.Bcp)] = Printer{ - Locale: loc, - printer: message.NewPrinter(lang), - } - } - } - DefaultPrinter = Printers["en"] -} - -func (p Printer) T(fmt string, args ...any) string { - return p.printer.Sprintf(fmt, args...) -} - -func (p Printer) Date(d time.Time) string { - return d.Format(p.Locale.dateFmt) -} - -/* TODO: Try to use a decimal type here */ -func (p Printer) Money(val float64, round bool) string { - var valstr string - - /* Hack to avoid gotext writing these two ‘translations’ into the - translations file */ - f := p.printer.Sprintf - if round { - valstr = f("%d", int(val)) - } else { - valstr = f("%.2f", val) - } - - /* All Eurozone languages place the eurosign after the value except - for Dutch, English, Gaelic, and Maltese. Austrian German also - uses Dutch-style formatting, but we do not support that dialect. */ - switch p.Locale.Bcp { - case "en", "en-US", "ga", "mt": - return fmt.Sprintf("€%s", valstr) - case "nl": - return fmt.Sprintf("€ %s", valstr) - default: - return fmt.Sprintf("%s €", valstr) - } -} - -/* Transform ‘en-US’ to ‘en’ */ -func (l Locale) Language() string { - return l.Bcp[:2] -} diff --git a/lib/countries.go b/lib/countries.go new file mode 100644 index 0000000..565f61c --- /dev/null +++ b/lib/countries.go @@ -0,0 +1,46 @@ +package lib + +import ( + "slices" + + "golang.org/x/text/collate" + "golang.org/x/text/language" +) + +type Country struct { + Code, Name string +} + +func SortedCountries(p Printer) []Country { + xs := []Country{ + {Code: "ad", Name: p.T("Andorra")}, + {Code: "at", Name: p.T("Austria")}, + {Code: "be", Name: p.T("Belgium")}, + {Code: "cy", Name: p.T("Cyprus")}, + {Code: "de", Name: p.T("Germany")}, + {Code: "ee", Name: p.T("Estonia")}, + {Code: "es", Name: p.T("Spain")}, + {Code: "fi", Name: p.T("Finland")}, + {Code: "fr", Name: p.T("France")}, + {Code: "gr", Name: p.T("Greece")}, + {Code: "hr", Name: p.T("Croatia")}, + {Code: "ie", Name: p.T("Ireland")}, + {Code: "it", Name: p.T("Italy")}, + {Code: "lt", Name: p.T("Lithuania")}, + {Code: "lu", Name: p.T("Luxembourg")}, + {Code: "lv", Name: p.T("Latvia")}, + {Code: "mc", Name: p.T("Monaco")}, + {Code: "mt", Name: p.T("Malta")}, + {Code: "nl", Name: p.T("Netherlands")}, + {Code: "pt", Name: p.T("Portugal")}, + {Code: "si", Name: p.T("Slovenia")}, + {Code: "sk", Name: p.T("Slovakia")}, + {Code: "sm", Name: p.T("San Marino")}, + {Code: "va", Name: p.T("Vatican City")}, + } + c := collate.New(language.MustParse(p.Locale.Bcp)) + slices.SortFunc(xs, func(x, y Country) int { + return c.CompareString(x.Name, y.Name) + }) + return xs +} diff --git a/lib/i18n.go b/lib/i18n.go new file mode 100644 index 0000000..50652cb --- /dev/null +++ b/lib/i18n.go @@ -0,0 +1,252 @@ +//go:generate gotext -srclang=en update -out=catalog.gen.go -lang=bg,el,en,nl git.thomasvoss.com/euro-cash.eu + +package lib + +import ( + "fmt" + "strings" + "time" + + "golang.org/x/text/language" + "golang.org/x/text/message" +) + +type Printer struct { + Locale Locale + inner *message.Printer +} + +type Locale struct { + Bcp, Name string + dateFmt, moneyFmt string + Eurozone, Enabled bool +} + +var ( + Locales = [...]Locale{ + { + Bcp: "ca", + Name: "català", + dateFmt: "2/1/2006", + Eurozone: true, + Enabled: false, + }, + { + Bcp: "de", + Name: "Deutsch", + dateFmt: "2.1.2006", + Eurozone: true, + Enabled: false, + }, + { + Bcp: "el", + Name: "ελληνικά", + dateFmt: "2/1/2006", + Eurozone: true, + Enabled: true, + }, + { + Bcp: "en", + Name: "English", + dateFmt: "02/01/2006", + Eurozone: true, + Enabled: true, + }, + { + Bcp: "es", + Name: "español", + dateFmt: "2/1/2006", + Eurozone: true, + Enabled: false, + }, + { + Bcp: "et", + Name: "eesti", + dateFmt: "2.1.2006", + Eurozone: true, + Enabled: false, + }, + { + Bcp: "fi", + Name: "suomi", + dateFmt: "2.1.2006", + Eurozone: true, + Enabled: false, + }, + { + Bcp: "fr", + Name: "français", + dateFmt: "02/01/2006", + Eurozone: true, + Enabled: false, + }, + { + Bcp: "ga", + Name: "Gaeilge", + dateFmt: "02/01/2006", + Eurozone: true, + Enabled: false, + }, + { + Bcp: "hr", + Name: "hrvatski", + dateFmt: "02. 01. 2006.", + Eurozone: true, + Enabled: false, + }, + { + Bcp: "it", + Name: "italiano", + dateFmt: "02/01/2006", + Eurozone: true, + Enabled: false, + }, + { + Bcp: "lb", + Name: "lëtzebuergesch", + dateFmt: "2.1.2006", + Eurozone: true, + Enabled: false, + }, + { + Bcp: "lt", + Name: "lietuvių", + dateFmt: "2006-01-02", + Eurozone: true, + Enabled: false, + }, + { + Bcp: "lv", + Name: "latviešu", + dateFmt: "2.01.2006.", + Eurozone: true, + Enabled: false, + }, + { + Bcp: "mt", + Name: "Malti", + dateFmt: "2/1/2006", + Eurozone: true, + Enabled: false, + }, + { + Bcp: "nl", + Name: "Nederlands", + dateFmt: "2-1-2006", + Eurozone: true, + Enabled: true, + }, + { + Bcp: "pt", + Name: "português", + dateFmt: "02/01/2006", + Eurozone: true, + Enabled: false, + }, + { + Bcp: "sk", + Name: "slovenčina", + dateFmt: "2. 1. 2006", + Eurozone: true, + Enabled: false, + }, + { + Bcp: "sl", + Name: "slovenščina", + dateFmt: "2. 1. 2006", + Eurozone: true, + Enabled: false, + }, + + /* Non-Eurozone locales */ + { + Bcp: "bg", + Name: "български", + dateFmt: "2.01.2006 г.", + Eurozone: false, + Enabled: true, + }, + { + Bcp: "en-US", + Name: "English (US)", + dateFmt: "1/2/2006", + Eurozone: false, + Enabled: false, + }, + { + Bcp: "ro", + Name: "română", + dateFmt: "02.01.2006", + Eurozone: false, + Enabled: false, + }, + { + Bcp: "uk", + Name: "yкраїнська", + dateFmt: "02.01.2006", + Eurozone: false, + Enabled: false, + }, + } + /* Map of language codes to Printers. We do this instead of just + using language.MustParse() directly so that we can easily see if a + language is supported or not. */ + Printers map[string]Printer = make(map[string]Printer, len(Locales)) + DefaultPrinter Printer +) + +func InitPrinters() { + for _, loc := range Locales { + if loc.Enabled { + lang := language.MustParse(loc.Bcp) + Printers[strings.ToLower(loc.Bcp)] = Printer{ + Locale: loc, + inner: message.NewPrinter(lang), + } + } + } + DefaultPrinter = Printers["en"] +} + +func (p Printer) T(fmt string, args ...any) string { + return p.inner.Sprintf(fmt, args...) +} + +func (p Printer) N(n int) string { + return p.inner.Sprint(n) +} + +func (p Printer) Date(d time.Time) string { + return d.Format(p.Locale.dateFmt) +} + +/* TODO: Try to use a decimal type here */ +func (p Printer) Money(val float64, round bool) string { + var valstr string + + /* Hack to avoid gotext writing these two ‘translations’ into the + translations file */ + f := p.inner.Sprintf + if round { + valstr = f("%d", int(val)) + } else { + valstr = f("%.2f", val) + } + + /* All Eurozone languages place the eurosign after the value except + for Dutch, English, Gaelic, and Maltese. Austrian German also + uses Dutch-style formatting, but we do not support that dialect. */ + switch p.Locale.Bcp { + case "en", "en-US", "ga", "mt": + return fmt.Sprintf("€%s", valstr) + case "nl": + return fmt.Sprintf("€ %s", valstr) + default: + return fmt.Sprintf("%s €", valstr) + } +} + +/* Transform ‘en-US’ to ‘en’ */ +func (l Locale) Language() string { + return l.Bcp[:2] +} diff --git a/lib/locales/bg/messages.gotext.json b/lib/locales/bg/messages.gotext.json new file mode 100644 index 0000000..d43d6f8 --- /dev/null +++ b/lib/locales/bg/messages.gotext.json @@ -0,0 +1,515 @@ +{ + "language": "bg", + "messages": [ + { + "id": "Page not found", + "message": "Page not found", + "translation": "" + }, + { + "id": "Andorra", + "message": "Andorra", + "translation": "Андора" + }, + { + "id": "Austria", + "message": "Austria", + "translation": "Австрия" + }, + { + "id": "Belgium", + "message": "Belgium", + "translation": "Белгия" + }, + { + "id": "Cyprus", + "message": "Cyprus", + "translation": "Кипър" + }, + { + "id": "Germany", + "message": "Germany", + "translation": "Германия" + }, + { + "id": "Estonia", + "message": "Estonia", + "translation": "Естония" + }, + { + "id": "Spain", + "message": "Spain", + "translation": "Испания" + }, + { + "id": "Finland", + "message": "Finland", + "translation": "Финландия" + }, + { + "id": "France", + "message": "France", + "translation": "Франция" + }, + { + "id": "Greece", + "message": "Greece", + "translation": "Гърция" + }, + { + "id": "Croatia", + "message": "Croatia", + "translation": "Хърватия" + }, + { + "id": "Ireland", + "message": "Ireland", + "translation": "Ирландия" + }, + { + "id": "Italy", + "message": "Italy", + "translation": "Италия" + }, + { + "id": "Lithuania", + "message": "Lithuania", + "translation": "Литва" + }, + { + "id": "Luxembourg", + "message": "Luxembourg", + "translation": "Люксембург" + }, + { + "id": "Latvia", + "message": "Latvia", + "translation": "Латвия" + }, + { + "id": "Monaco", + "message": "Monaco", + "translation": "Монако" + }, + { + "id": "Malta", + "message": "Malta", + "translation": "Малта" + }, + { + "id": "Netherlands", + "message": "Netherlands", + "translation": "Холандия" + }, + { + "id": "Portugal", + "message": "Portugal", + "translation": "Португалия" + }, + { + "id": "Slovenia", + "message": "Slovenia", + "translation": "Словения" + }, + { + "id": "Slovakia", + "message": "Slovakia", + "translation": "Словакия" + }, + { + "id": "San Marino", + "message": "San Marino", + "translation": "Сан Марино" + }, + { + "id": "Vatican City", + "message": "Vatican City", + "translation": "град Ватикана" + }, + { + "id": "About Us", + "message": "About Us", + "translation": "" + }, + { + "id": "Open Source", + "message": "Open Source", + "translation": "" + }, + { + "id": "This website is an open project, and a collaboration between developers, translators, and researchers. All source code, data, images, and more for the website are open source and can be found {RepoLinkStart}here{LinkEnd}. This site is licensed under the BSD 0-Clause license giving you the full freedom to do whatever you would like with any of the content on this site.", + "message": "This website is an open project, and a collaboration between developers, translators, and researchers. All source code, data, images, and more for the website are open source and can be found {RepoLinkStart}here{LinkEnd}. This site is licensed under the BSD 0-Clause license giving you the full freedom to do whatever you would like with any of the content on this site.", + "translation": "", + "placeholders": [ + { + "id": "RepoLinkStart", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "repoLinkStart" + }, + { + "id": "LinkEnd", + "string": "%[2]s", + "type": "string", + "underlyingType": "string", + "argNum": 2, + "expr": "linkEnd" + } + ] + }, + { + "id": "Contact Us", + "message": "Contact Us", + "translation": "" + }, + { + "id": "While we try to stay as up-to-date as possible and to fact check our information, it is always possible that we get something wrong, lack a translation, or are missing some piece of data you may have. In such a case don’t hesitate to contact us; we’ll try to get the site updated or fixed as soon as possible. You are always free to contribute via a git patch if you are more technically included, but if not you can always send an email to {ContactEmail} or contact ‘@onetruemangoman’ on Discord.", + "message": "While we try to stay as up-to-date as possible and to fact check our information, it is always possible that we get something wrong, lack a translation, or are missing some piece of data you may have. In such a case don’t hesitate to contact us; we’ll try to get the site updated or fixed as soon as possible. You are always free to contribute via a git patch if you are more technically included, but if not you can always send an email to {ContactEmail} or contact ‘@onetruemangoman’ on Discord.", + "translation": "", + "placeholders": [ + { + "id": "ContactEmail", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "contactEmail" + } + ] + }, + { + "id": "Special Thanks", + "message": "Special Thanks", + "translation": "" + }, + { + "id": "Development", + "message": "Development", + "translation": "" + }, + { + "id": "Research", + "message": "Research", + "translation": "" + }, + { + "id": "Translations", + "message": "Translations", + "translation": "" + }, + { + "id": "British- \u0026 American English", + "message": "British- \u0026 American English", + "translation": "" + }, + { + "id": "Icelandic", + "message": "Icelandic", + "translation": "" + }, + { + "id": "Found a mistake or want to contribute missing information?", + "message": "Found a mistake or want to contribute missing information?", + "translation": "" + }, + { + "id": "Feel free to contact us!", + "message": "Feel free to contact us!", + "translation": "" + }, + { + "id": "Dutch Euro Coin Designs", + "message": "Dutch Euro Coin Designs", + "translation": "" + }, + { + "id": "From the years 1999–2013 all Dutch euro coins featured the portrait of Queen Beatrix of the Netherlands. After her abdication from the throne in 2013 the designs of all denominations were changed to feature the portrait of the new King Willem-Alexander. After her abdication the direction in which the monarchs portrait faced was flipped; a tradition dating back to the earliest coins of the Kingdom of the Netherlands.", + "message": "From the years 1999–2013 all Dutch euro coins featured the portrait of Queen Beatrix of the Netherlands. After her abdication from the throne in 2013 the designs of all denominations were changed to feature the portrait of the new King Willem-Alexander. After her abdication the direction in which the monarchs portrait faced was flipped; a tradition dating back to the earliest coins of the Kingdom of the Netherlands.", + "translation": "" + }, + { + "id": "Coins featuring both monarchs contain text reading ‘BEATRIX KONINGIN DER NEDERLANDEN’ (‘BEATRIX QUEEN OF THE NETHERLANDS’) and ‘Willem-Alexander Koning der Nederlanden’ (‘Willem-Alexander King of the Netherlands’) respectively.", + "message": "Coins featuring both monarchs contain text reading ‘BEATRIX KONINGIN DER NEDERLANDEN’ (‘BEATRIX QUEEN OF THE NETHERLANDS’) and ‘Willem-Alexander Koning der Nederlanden’ (‘Willem-Alexander King of the Netherlands’) respectively.", + "translation": "" + }, + { + "id": "The €1 and €2 coins featuring King Willem-Alexander were minted with a much lower relief than most euro coins of the same denomination. As a result it is not uncommon for these coins to appear worn after little use in circulation.", + "message": "The €1 and €2 coins featuring King Willem-Alexander were minted with a much lower relief than most euro coins of the same denomination. As a result it is not uncommon for these coins to appear worn after little use in circulation.", + "translation": "" + }, + { + "id": "Euro Coin Designs", + "message": "Euro Coin Designs", + "translation": "" + }, + { + "id": "Here you’ll be able to view all the coin designs for each country in the Eurozone. This section of the site doesn’t include minor varieties such as different mintmarks or errors; those are on the {VarietiesLinkStart}varieties{LinkEnd} page.", + "message": "Here you’ll be able to view all the coin designs for each country in the Eurozone. This section of the site doesn’t include minor varieties such as different mintmarks or errors; those are on the {VarietiesLinkStart}varieties{LinkEnd} page.", + "translation": "", + "placeholders": [ + { + "id": "VarietiesLinkStart", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "varietiesLinkStart" + }, + { + "id": "LinkEnd", + "string": "%[2]s", + "type": "string", + "underlyingType": "string", + "argNum": 2, + "expr": "linkEnd" + } + ] + }, + { + "id": "Euro Coin Mintages", + "message": "Euro Coin Mintages", + "translation": "" + }, + { + "id": "Here you’ll be able to view all the known mintages for all coins. You’ll also be able to filter on country, denomination, etc. If you have any mintage data that’s missing from our site, feel free to contact us.", + "message": "Here you’ll be able to view all the known mintages for all coins. You’ll also be able to filter on country, denomination, etc. If you have any mintage data that’s missing from our site, feel free to contact us.", + "translation": "" + }, + { + "id": "Additional Notes", + "message": "Additional Notes", + "translation": "" + }, + { + "id": "Most coins from the years 2003–2016 are listed as NIFC coins while other popular sources such as Numista claim they were minted for circulation. For more information on why others are wrong, {MuntrolpakketLinkStart}click here{LinkEnd}.", + "message": "Most coins from the years 2003–2016 are listed as NIFC coins while other popular sources such as Numista claim they were minted for circulation. For more information on why others are wrong, {MuntrolpakketLinkStart}click here{LinkEnd}.", + "translation": "", + "placeholders": [ + { + "id": "MuntrolpakketLinkStart", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "muntrolpakketLinkStart" + }, + { + "id": "LinkEnd", + "string": "%[2]s", + "type": "string", + "underlyingType": "string", + "argNum": 2, + "expr": "linkEnd" + } + ] + }, + { + "id": "In 2003 Numista calculated a total of {217503} coins issued for coin sets per denomination. Our own calculations found only {177003}. Numista also forgot to include the many hundred thousand coins from the coin roll sets that were produced.", + "message": "In 2003 Numista calculated a total of {217503} coins issued for coin sets per denomination. Our own calculations found only {177003}. Numista also forgot to include the many hundred thousand coins from the coin roll sets that were produced.", + "translation": "", + "placeholders": [ + { + "id": "217503", + "string": "%[1]d", + "type": "int", + "underlyingType": "int", + "argNum": 1, + "expr": "217503" + }, + { + "id": "177003", + "string": "%[2]d", + "type": "int", + "underlyingType": "int", + "argNum": 2, + "expr": "177003" + } + ] + }, + { + "id": "Country", + "message": "Country", + "translation": "" + }, + { + "id": "Circulation Coins", + "message": "Circulation Coins", + "translation": "" + }, + { + "id": "NIFC / BU Sets", + "message": "NIFC / BU Sets", + "translation": "" + }, + { + "id": "Proof Coins", + "message": "Proof Coins", + "translation": "" + }, + { + "id": "Filter", + "message": "Filter", + "translation": "" + }, + { + "id": "Year", + "message": "Year", + "translation": "" + }, + { + "id": "Unknown", + "message": "Unknown", + "translation": "" + }, + { + "id": "Euro Coins", + "message": "Euro Coins", + "translation": "" + }, + { + "id": "On this section of the site you can find everything there is to know about the coins of the Eurozone. For the latest news on coin- and design releases, check out the {NewsLinkStart}news{LinkEnd} tab!", + "message": "On this section of the site you can find everything there is to know about the coins of the Eurozone. For the latest news on coin- and design releases, check out the {NewsLinkStart}news{LinkEnd} tab!", + "translation": "", + "placeholders": [ + { + "id": "NewsLinkStart", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "newsLinkStart" + }, + { + "id": "LinkEnd", + "string": "%[2]s", + "type": "string", + "underlyingType": "string", + "argNum": 2, + "expr": "linkEnd" + } + ] + }, + { + "id": "Designs", + "message": "Designs", + "translation": "" + }, + { + "id": "View the 600+ different Euro-coin designs!", + "message": "View the 600+ different Euro-coin designs!", + "translation": "" + }, + { + "id": "Mintages", + "message": "Mintages", + "translation": "" + }, + { + "id": "View the mintage figures of all the Euro coins!", + "message": "View the mintage figures of all the Euro coins!", + "translation": "" + }, + { + "id": "Varieties", + "message": "Varieties", + "translation": "" + }, + { + "id": "View all the known Euro varieties!", + "message": "View all the known Euro varieties!", + "translation": "" + }, + { + "id": "Select Your Language", + "message": "Select Your Language", + "translation": "" + }, + { + "id": "Select your preferred language to use on the site.", + "message": "Select your preferred language to use on the site.", + "translation": "" + }, + { + "id": "Eurozone Languages", + "message": "Eurozone Languages", + "translation": "" + }, + { + "id": "Other Languages", + "message": "Other Languages", + "translation": "" + }, + { + "id": "Home", + "message": "Home", + "translation": "" + }, + { + "id": "News", + "message": "News", + "translation": "" + }, + { + "id": "Coin Collecting", + "message": "Coin Collecting", + "translation": "" + }, + { + "id": "Coins", + "message": "Coins", + "translation": "" + }, + { + "id": "Banknotes", + "message": "Banknotes", + "translation": "" + }, + { + "id": "Jargon", + "message": "Jargon", + "translation": "" + }, + { + "id": "Discord", + "message": "Discord", + "translation": "" + }, + { + "id": "About", + "message": "About", + "translation": "" + }, + { + "id": "Language", + "message": "Language", + "translation": "" + }, + { + "id": "The Euro Cash Compendium", + "message": "The Euro Cash Compendium", + "translation": "" + }, + { + "id": "United in", + "message": "United in", + "translation": "" + }, + { + "id": "diversity", + "message": "diversity", + "translation": "" + }, + { + "id": "cash", + "message": "cash", + "translation": "" + }, + { + "id": "Welcome to the Euro Cash Compendium. This sites aims to be a resource for you to discover everything there is to know about the coins and banknotes of the Euro, a currency that spans 26 countries and 350 million people. We also have dedicated sections of the site for collectors.", + "message": "Welcome to the Euro Cash Compendium. This sites aims to be a resource for you to discover everything there is to know about the coins and banknotes of the Euro, a currency that spans 26 countries and 350 million people. We also have dedicated sections of the site for collectors.", + "translation": "" + } + ] +} \ No newline at end of file diff --git a/lib/locales/el/messages.gotext.json b/lib/locales/el/messages.gotext.json new file mode 100644 index 0000000..278c3fa --- /dev/null +++ b/lib/locales/el/messages.gotext.json @@ -0,0 +1,515 @@ +{ + "language": "el", + "messages": [ + { + "id": "Page not found", + "message": "Page not found", + "translation": "" + }, + { + "id": "Andorra", + "message": "Andorra", + "translation": "Ανδόρα" + }, + { + "id": "Austria", + "message": "Austria", + "translation": "Αυστρία" + }, + { + "id": "Belgium", + "message": "Belgium", + "translation": "Βέλγιο" + }, + { + "id": "Cyprus", + "message": "Cyprus", + "translation": "Κύπρος" + }, + { + "id": "Germany", + "message": "Germany", + "translation": "Γερμανία" + }, + { + "id": "Estonia", + "message": "Estonia", + "translation": "Εσθονία" + }, + { + "id": "Spain", + "message": "Spain", + "translation": "Ισπανία" + }, + { + "id": "Finland", + "message": "Finland", + "translation": "Φινλανδία" + }, + { + "id": "France", + "message": "France", + "translation": "Γαλλία" + }, + { + "id": "Greece", + "message": "Greece", + "translation": "Ελλάδα" + }, + { + "id": "Croatia", + "message": "Croatia", + "translation": "Κροατία" + }, + { + "id": "Ireland", + "message": "Ireland", + "translation": "Ιρλανδία" + }, + { + "id": "Italy", + "message": "Italy", + "translation": "Ιταλία" + }, + { + "id": "Lithuania", + "message": "Lithuania", + "translation": "Λιθουανία" + }, + { + "id": "Luxembourg", + "message": "Luxembourg", + "translation": "Λουξεμβούργο" + }, + { + "id": "Latvia", + "message": "Latvia", + "translation": "Λετονία" + }, + { + "id": "Monaco", + "message": "Monaco", + "translation": "Μονακό" + }, + { + "id": "Malta", + "message": "Malta", + "translation": "Μάλτα" + }, + { + "id": "Netherlands", + "message": "Netherlands", + "translation": "Ολλανδία" + }, + { + "id": "Portugal", + "message": "Portugal", + "translation": "Πορτογαλία" + }, + { + "id": "Slovenia", + "message": "Slovenia", + "translation": "Σλοβενία" + }, + { + "id": "Slovakia", + "message": "Slovakia", + "translation": "Σλοβακία" + }, + { + "id": "San Marino", + "message": "San Marino", + "translation": "Σαν Μαρίνο" + }, + { + "id": "Vatican City", + "message": "Vatican City", + "translation": "Βατικανό" + }, + { + "id": "About Us", + "message": "About Us", + "translation": "" + }, + { + "id": "Open Source", + "message": "Open Source", + "translation": "" + }, + { + "id": "This website is an open project, and a collaboration between developers, translators, and researchers. All source code, data, images, and more for the website are open source and can be found {RepoLinkStart}here{LinkEnd}. This site is licensed under the BSD 0-Clause license giving you the full freedom to do whatever you would like with any of the content on this site.", + "message": "This website is an open project, and a collaboration between developers, translators, and researchers. All source code, data, images, and more for the website are open source and can be found {RepoLinkStart}here{LinkEnd}. This site is licensed under the BSD 0-Clause license giving you the full freedom to do whatever you would like with any of the content on this site.", + "translation": "", + "placeholders": [ + { + "id": "RepoLinkStart", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "repoLinkStart" + }, + { + "id": "LinkEnd", + "string": "%[2]s", + "type": "string", + "underlyingType": "string", + "argNum": 2, + "expr": "linkEnd" + } + ] + }, + { + "id": "Contact Us", + "message": "Contact Us", + "translation": "" + }, + { + "id": "While we try to stay as up-to-date as possible and to fact check our information, it is always possible that we get something wrong, lack a translation, or are missing some piece of data you may have. In such a case don’t hesitate to contact us; we’ll try to get the site updated or fixed as soon as possible. You are always free to contribute via a git patch if you are more technically included, but if not you can always send an email to {ContactEmail} or contact ‘@onetruemangoman’ on Discord.", + "message": "While we try to stay as up-to-date as possible and to fact check our information, it is always possible that we get something wrong, lack a translation, or are missing some piece of data you may have. In such a case don’t hesitate to contact us; we’ll try to get the site updated or fixed as soon as possible. You are always free to contribute via a git patch if you are more technically included, but if not you can always send an email to {ContactEmail} or contact ‘@onetruemangoman’ on Discord.", + "translation": "", + "placeholders": [ + { + "id": "ContactEmail", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "contactEmail" + } + ] + }, + { + "id": "Special Thanks", + "message": "Special Thanks", + "translation": "" + }, + { + "id": "Development", + "message": "Development", + "translation": "" + }, + { + "id": "Research", + "message": "Research", + "translation": "" + }, + { + "id": "Translations", + "message": "Translations", + "translation": "" + }, + { + "id": "British- \u0026 American English", + "message": "British- \u0026 American English", + "translation": "" + }, + { + "id": "Icelandic", + "message": "Icelandic", + "translation": "" + }, + { + "id": "Found a mistake or want to contribute missing information?", + "message": "Found a mistake or want to contribute missing information?", + "translation": "" + }, + { + "id": "Feel free to contact us!", + "message": "Feel free to contact us!", + "translation": "" + }, + { + "id": "Dutch Euro Coin Designs", + "message": "Dutch Euro Coin Designs", + "translation": "" + }, + { + "id": "From the years 1999–2013 all Dutch euro coins featured the portrait of Queen Beatrix of the Netherlands. After her abdication from the throne in 2013 the designs of all denominations were changed to feature the portrait of the new King Willem-Alexander. After her abdication the direction in which the monarchs portrait faced was flipped; a tradition dating back to the earliest coins of the Kingdom of the Netherlands.", + "message": "From the years 1999–2013 all Dutch euro coins featured the portrait of Queen Beatrix of the Netherlands. After her abdication from the throne in 2013 the designs of all denominations were changed to feature the portrait of the new King Willem-Alexander. After her abdication the direction in which the monarchs portrait faced was flipped; a tradition dating back to the earliest coins of the Kingdom of the Netherlands.", + "translation": "" + }, + { + "id": "Coins featuring both monarchs contain text reading ‘BEATRIX KONINGIN DER NEDERLANDEN’ (‘BEATRIX QUEEN OF THE NETHERLANDS’) and ‘Willem-Alexander Koning der Nederlanden’ (‘Willem-Alexander King of the Netherlands’) respectively.", + "message": "Coins featuring both monarchs contain text reading ‘BEATRIX KONINGIN DER NEDERLANDEN’ (‘BEATRIX QUEEN OF THE NETHERLANDS’) and ‘Willem-Alexander Koning der Nederlanden’ (‘Willem-Alexander King of the Netherlands’) respectively.", + "translation": "" + }, + { + "id": "The €1 and €2 coins featuring King Willem-Alexander were minted with a much lower relief than most euro coins of the same denomination. As a result it is not uncommon for these coins to appear worn after little use in circulation.", + "message": "The €1 and €2 coins featuring King Willem-Alexander were minted with a much lower relief than most euro coins of the same denomination. As a result it is not uncommon for these coins to appear worn after little use in circulation.", + "translation": "" + }, + { + "id": "Euro Coin Designs", + "message": "Euro Coin Designs", + "translation": "" + }, + { + "id": "Here you’ll be able to view all the coin designs for each country in the Eurozone. This section of the site doesn’t include minor varieties such as different mintmarks or errors; those are on the {VarietiesLinkStart}varieties{LinkEnd} page.", + "message": "Here you’ll be able to view all the coin designs for each country in the Eurozone. This section of the site doesn’t include minor varieties such as different mintmarks or errors; those are on the {VarietiesLinkStart}varieties{LinkEnd} page.", + "translation": "", + "placeholders": [ + { + "id": "VarietiesLinkStart", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "varietiesLinkStart" + }, + { + "id": "LinkEnd", + "string": "%[2]s", + "type": "string", + "underlyingType": "string", + "argNum": 2, + "expr": "linkEnd" + } + ] + }, + { + "id": "Euro Coin Mintages", + "message": "Euro Coin Mintages", + "translation": "" + }, + { + "id": "Here you’ll be able to view all the known mintages for all coins. You’ll also be able to filter on country, denomination, etc. If you have any mintage data that’s missing from our site, feel free to contact us.", + "message": "Here you’ll be able to view all the known mintages for all coins. You’ll also be able to filter on country, denomination, etc. If you have any mintage data that’s missing from our site, feel free to contact us.", + "translation": "" + }, + { + "id": "Additional Notes", + "message": "Additional Notes", + "translation": "" + }, + { + "id": "Most coins from the years 2003–2016 are listed as NIFC coins while other popular sources such as Numista claim they were minted for circulation. For more information on why others are wrong, {MuntrolpakketLinkStart}click here{LinkEnd}.", + "message": "Most coins from the years 2003–2016 are listed as NIFC coins while other popular sources such as Numista claim they were minted for circulation. For more information on why others are wrong, {MuntrolpakketLinkStart}click here{LinkEnd}.", + "translation": "", + "placeholders": [ + { + "id": "MuntrolpakketLinkStart", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "muntrolpakketLinkStart" + }, + { + "id": "LinkEnd", + "string": "%[2]s", + "type": "string", + "underlyingType": "string", + "argNum": 2, + "expr": "linkEnd" + } + ] + }, + { + "id": "In 2003 Numista calculated a total of {217503} coins issued for coin sets per denomination. Our own calculations found only {177003}. Numista also forgot to include the many hundred thousand coins from the coin roll sets that were produced.", + "message": "In 2003 Numista calculated a total of {217503} coins issued for coin sets per denomination. Our own calculations found only {177003}. Numista also forgot to include the many hundred thousand coins from the coin roll sets that were produced.", + "translation": "", + "placeholders": [ + { + "id": "217503", + "string": "%[1]d", + "type": "int", + "underlyingType": "int", + "argNum": 1, + "expr": "217503" + }, + { + "id": "177003", + "string": "%[2]d", + "type": "int", + "underlyingType": "int", + "argNum": 2, + "expr": "177003" + } + ] + }, + { + "id": "Country", + "message": "Country", + "translation": "" + }, + { + "id": "Circulation Coins", + "message": "Circulation Coins", + "translation": "" + }, + { + "id": "NIFC / BU Sets", + "message": "NIFC / BU Sets", + "translation": "" + }, + { + "id": "Proof Coins", + "message": "Proof Coins", + "translation": "" + }, + { + "id": "Filter", + "message": "Filter", + "translation": "" + }, + { + "id": "Year", + "message": "Year", + "translation": "" + }, + { + "id": "Unknown", + "message": "Unknown", + "translation": "" + }, + { + "id": "Euro Coins", + "message": "Euro Coins", + "translation": "" + }, + { + "id": "On this section of the site you can find everything there is to know about the coins of the Eurozone. For the latest news on coin- and design releases, check out the {NewsLinkStart}news{LinkEnd} tab!", + "message": "On this section of the site you can find everything there is to know about the coins of the Eurozone. For the latest news on coin- and design releases, check out the {NewsLinkStart}news{LinkEnd} tab!", + "translation": "", + "placeholders": [ + { + "id": "NewsLinkStart", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "newsLinkStart" + }, + { + "id": "LinkEnd", + "string": "%[2]s", + "type": "string", + "underlyingType": "string", + "argNum": 2, + "expr": "linkEnd" + } + ] + }, + { + "id": "Designs", + "message": "Designs", + "translation": "" + }, + { + "id": "View the 600+ different Euro-coin designs!", + "message": "View the 600+ different Euro-coin designs!", + "translation": "" + }, + { + "id": "Mintages", + "message": "Mintages", + "translation": "" + }, + { + "id": "View the mintage figures of all the Euro coins!", + "message": "View the mintage figures of all the Euro coins!", + "translation": "" + }, + { + "id": "Varieties", + "message": "Varieties", + "translation": "" + }, + { + "id": "View all the known Euro varieties!", + "message": "View all the known Euro varieties!", + "translation": "" + }, + { + "id": "Select Your Language", + "message": "Select Your Language", + "translation": "" + }, + { + "id": "Select your preferred language to use on the site.", + "message": "Select your preferred language to use on the site.", + "translation": "" + }, + { + "id": "Eurozone Languages", + "message": "Eurozone Languages", + "translation": "" + }, + { + "id": "Other Languages", + "message": "Other Languages", + "translation": "" + }, + { + "id": "Home", + "message": "Home", + "translation": "" + }, + { + "id": "News", + "message": "News", + "translation": "" + }, + { + "id": "Coin Collecting", + "message": "Coin Collecting", + "translation": "" + }, + { + "id": "Coins", + "message": "Coins", + "translation": "" + }, + { + "id": "Banknotes", + "message": "Banknotes", + "translation": "" + }, + { + "id": "Jargon", + "message": "Jargon", + "translation": "" + }, + { + "id": "Discord", + "message": "Discord", + "translation": "" + }, + { + "id": "About", + "message": "About", + "translation": "" + }, + { + "id": "Language", + "message": "Language", + "translation": "" + }, + { + "id": "The Euro Cash Compendium", + "message": "The Euro Cash Compendium", + "translation": "" + }, + { + "id": "United in", + "message": "United in", + "translation": "" + }, + { + "id": "diversity", + "message": "diversity", + "translation": "" + }, + { + "id": "cash", + "message": "cash", + "translation": "" + }, + { + "id": "Welcome to the Euro Cash Compendium. This sites aims to be a resource for you to discover everything there is to know about the coins and banknotes of the Euro, a currency that spans 26 countries and 350 million people. We also have dedicated sections of the site for collectors.", + "message": "Welcome to the Euro Cash Compendium. This sites aims to be a resource for you to discover everything there is to know about the coins and banknotes of the Euro, a currency that spans 26 countries and 350 million people. We also have dedicated sections of the site for collectors.", + "translation": "" + } + ] +} \ No newline at end of file diff --git a/lib/locales/en/messages.gotext.json b/lib/locales/en/messages.gotext.json new file mode 100644 index 0000000..cfe64f2 --- /dev/null +++ b/lib/locales/en/messages.gotext.json @@ -0,0 +1,679 @@ +{ + "language": "en", + "messages": [ + { + "id": "Page not found", + "message": "Page not found", + "translation": "Page not found", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Andorra", + "message": "Andorra", + "translation": "Andorra", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Austria", + "message": "Austria", + "translation": "Austria", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Belgium", + "message": "Belgium", + "translation": "Belgium", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Cyprus", + "message": "Cyprus", + "translation": "Cyprus", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Germany", + "message": "Germany", + "translation": "Germany", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Estonia", + "message": "Estonia", + "translation": "Estonia", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Spain", + "message": "Spain", + "translation": "Spain", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Finland", + "message": "Finland", + "translation": "Finland", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "France", + "message": "France", + "translation": "France", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Greece", + "message": "Greece", + "translation": "Greece", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Croatia", + "message": "Croatia", + "translation": "Croatia", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Ireland", + "message": "Ireland", + "translation": "Ireland", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Italy", + "message": "Italy", + "translation": "Italy", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Lithuania", + "message": "Lithuania", + "translation": "Lithuania", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Luxembourg", + "message": "Luxembourg", + "translation": "Luxembourg", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Latvia", + "message": "Latvia", + "translation": "Latvia", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Monaco", + "message": "Monaco", + "translation": "Monaco", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Malta", + "message": "Malta", + "translation": "Malta", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Netherlands", + "message": "Netherlands", + "translation": "Netherlands", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Portugal", + "message": "Portugal", + "translation": "Portugal", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Slovenia", + "message": "Slovenia", + "translation": "Slovenia", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Slovakia", + "message": "Slovakia", + "translation": "Slovakia", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "San Marino", + "message": "San Marino", + "translation": "San Marino", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Vatican City", + "message": "Vatican City", + "translation": "Vatican City", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "About Us", + "message": "About Us", + "translation": "About Us", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Open Source", + "message": "Open Source", + "translation": "Open Source", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "This website is an open project, and a collaboration between developers, translators, and researchers. All source code, data, images, and more for the website are open source and can be found {RepoLinkStart}here{LinkEnd}. This site is licensed under the BSD 0-Clause license giving you the full freedom to do whatever you would like with any of the content on this site.", + "message": "This website is an open project, and a collaboration between developers, translators, and researchers. All source code, data, images, and more for the website are open source and can be found {RepoLinkStart}here{LinkEnd}. This site is licensed under the BSD 0-Clause license giving you the full freedom to do whatever you would like with any of the content on this site.", + "translation": "This website is an open project, and a collaboration between developers, translators, and researchers. All source code, data, images, and more for the website are open source and can be found {RepoLinkStart}here{LinkEnd}. This site is licensed under the BSD 0-Clause license giving you the full freedom to do whatever you would like with any of the content on this site.", + "translatorComment": "Copied from source.", + "placeholders": [ + { + "id": "RepoLinkStart", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "repoLinkStart" + }, + { + "id": "LinkEnd", + "string": "%[2]s", + "type": "string", + "underlyingType": "string", + "argNum": 2, + "expr": "linkEnd" + } + ], + "fuzzy": true + }, + { + "id": "Contact Us", + "message": "Contact Us", + "translation": "Contact Us", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "While we try to stay as up-to-date as possible and to fact check our information, it is always possible that we get something wrong, lack a translation, or are missing some piece of data you may have. In such a case don’t hesitate to contact us; we’ll try to get the site updated or fixed as soon as possible. You are always free to contribute via a git patch if you are more technically included, but if not you can always send an email to {ContactEmail} or contact ‘@onetruemangoman’ on Discord.", + "message": "While we try to stay as up-to-date as possible and to fact check our information, it is always possible that we get something wrong, lack a translation, or are missing some piece of data you may have. In such a case don’t hesitate to contact us; we’ll try to get the site updated or fixed as soon as possible. You are always free to contribute via a git patch if you are more technically included, but if not you can always send an email to {ContactEmail} or contact ‘@onetruemangoman’ on Discord.", + "translation": "While we try to stay as up-to-date as possible and to fact check our information, it is always possible that we get something wrong, lack a translation, or are missing some piece of data you may have. In such a case don’t hesitate to contact us; we’ll try to get the site updated or fixed as soon as possible. You are always free to contribute via a git patch if you are more technically included, but if not you can always send an email to {ContactEmail} or contact ‘@onetruemangoman’ on Discord.", + "translatorComment": "Copied from source.", + "placeholders": [ + { + "id": "ContactEmail", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "contactEmail" + } + ], + "fuzzy": true + }, + { + "id": "Special Thanks", + "message": "Special Thanks", + "translation": "Special Thanks", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Development", + "message": "Development", + "translation": "Development", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Research", + "message": "Research", + "translation": "Research", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Translations", + "message": "Translations", + "translation": "Translations", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "British- \u0026 American English", + "message": "British- \u0026 American English", + "translation": "British- \u0026 American English", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Icelandic", + "message": "Icelandic", + "translation": "Icelandic", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Found a mistake or want to contribute missing information?", + "message": "Found a mistake or want to contribute missing information?", + "translation": "Found a mistake or want to contribute missing information?", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Feel free to contact us!", + "message": "Feel free to contact us!", + "translation": "Feel free to contact us!", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Dutch Euro Coin Designs", + "message": "Dutch Euro Coin Designs", + "translation": "Dutch Euro Coin Designs", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "From the years 1999–2013 all Dutch euro coins featured the portrait of Queen Beatrix of the Netherlands. After her abdication from the throne in 2013 the designs of all denominations were changed to feature the portrait of the new King Willem-Alexander. After her abdication the direction in which the monarchs portrait faced was flipped; a tradition dating back to the earliest coins of the Kingdom of the Netherlands.", + "message": "From the years 1999–2013 all Dutch euro coins featured the portrait of Queen Beatrix of the Netherlands. After her abdication from the throne in 2013 the designs of all denominations were changed to feature the portrait of the new King Willem-Alexander. After her abdication the direction in which the monarchs portrait faced was flipped; a tradition dating back to the earliest coins of the Kingdom of the Netherlands.", + "translation": "From the years 1999–2013 all Dutch euro coins featured the portrait of Queen Beatrix of the Netherlands. After her abdication from the throne in 2013 the designs of all denominations were changed to feature the portrait of the new King Willem-Alexander. After her abdication the direction in which the monarchs portrait faced was flipped; a tradition dating back to the earliest coins of the Kingdom of the Netherlands.", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Coins featuring both monarchs contain text reading ‘BEATRIX KONINGIN DER NEDERLANDEN’ (‘BEATRIX QUEEN OF THE NETHERLANDS’) and ‘Willem-Alexander Koning der Nederlanden’ (‘Willem-Alexander King of the Netherlands’) respectively.", + "message": "Coins featuring both monarchs contain text reading ‘BEATRIX KONINGIN DER NEDERLANDEN’ (‘BEATRIX QUEEN OF THE NETHERLANDS’) and ‘Willem-Alexander Koning der Nederlanden’ (‘Willem-Alexander King of the Netherlands’) respectively.", + "translation": "Coins featuring both monarchs contain text reading ‘BEATRIX KONINGIN DER NEDERLANDEN’ (‘BEATRIX QUEEN OF THE NETHERLANDS’) and ‘Willem-Alexander Koning der Nederlanden’ (‘Willem-Alexander King of the Netherlands’) respectively.", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "The €1 and €2 coins featuring King Willem-Alexander were minted with a much lower relief than most euro coins of the same denomination. As a result it is not uncommon for these coins to appear worn after little use in circulation.", + "message": "The €1 and €2 coins featuring King Willem-Alexander were minted with a much lower relief than most euro coins of the same denomination. As a result it is not uncommon for these coins to appear worn after little use in circulation.", + "translation": "The €1 and €2 coins featuring King Willem-Alexander were minted with a much lower relief than most euro coins of the same denomination. As a result it is not uncommon for these coins to appear worn after little use in circulation.", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Euro Coin Designs", + "message": "Euro Coin Designs", + "translation": "Euro Coin Designs", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Here you’ll be able to view all the coin designs for each country in the Eurozone. This section of the site doesn’t include minor varieties such as different mintmarks or errors; those are on the {VarietiesLinkStart}varieties{LinkEnd} page.", + "message": "Here you’ll be able to view all the coin designs for each country in the Eurozone. This section of the site doesn’t include minor varieties such as different mintmarks or errors; those are on the {VarietiesLinkStart}varieties{LinkEnd} page.", + "translation": "Here you’ll be able to view all the coin designs for each country in the Eurozone. This section of the site doesn’t include minor varieties such as different mintmarks or errors; those are on the {VarietiesLinkStart}varieties{LinkEnd} page.", + "translatorComment": "Copied from source.", + "placeholders": [ + { + "id": "VarietiesLinkStart", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "varietiesLinkStart" + }, + { + "id": "LinkEnd", + "string": "%[2]s", + "type": "string", + "underlyingType": "string", + "argNum": 2, + "expr": "linkEnd" + } + ], + "fuzzy": true + }, + { + "id": "Euro Coin Mintages", + "message": "Euro Coin Mintages", + "translation": "Euro Coin Mintages", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Here you’ll be able to view all the known mintages for all coins. You’ll also be able to filter on country, denomination, etc. If you have any mintage data that’s missing from our site, feel free to contact us.", + "message": "Here you’ll be able to view all the known mintages for all coins. You’ll also be able to filter on country, denomination, etc. If you have any mintage data that’s missing from our site, feel free to contact us.", + "translation": "Here you’ll be able to view all the known mintages for all coins. You’ll also be able to filter on country, denomination, etc. If you have any mintage data that’s missing from our site, feel free to contact us.", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Additional Notes", + "message": "Additional Notes", + "translation": "Additional Notes", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Most coins from the years 2003–2016 are listed as NIFC coins while other popular sources such as Numista claim they were minted for circulation. For more information on why others are wrong, {MuntrolpakketLinkStart}click here{LinkEnd}.", + "message": "Most coins from the years 2003–2016 are listed as NIFC coins while other popular sources such as Numista claim they were minted for circulation. For more information on why others are wrong, {MuntrolpakketLinkStart}click here{LinkEnd}.", + "translation": "Most coins from the years 2003–2016 are listed as NIFC coins while other popular sources such as Numista claim they were minted for circulation. For more information on why others are wrong, {MuntrolpakketLinkStart}click here{LinkEnd}.", + "translatorComment": "Copied from source.", + "placeholders": [ + { + "id": "MuntrolpakketLinkStart", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "muntrolpakketLinkStart" + }, + { + "id": "LinkEnd", + "string": "%[2]s", + "type": "string", + "underlyingType": "string", + "argNum": 2, + "expr": "linkEnd" + } + ], + "fuzzy": true + }, + { + "id": "In 2003 Numista calculated a total of {217503} coins issued for coin sets per denomination. Our own calculations found only {177003}. Numista also forgot to include the many hundred thousand coins from the coin roll sets that were produced.", + "message": "In 2003 Numista calculated a total of {217503} coins issued for coin sets per denomination. Our own calculations found only {177003}. Numista also forgot to include the many hundred thousand coins from the coin roll sets that were produced.", + "translation": "In 2003 Numista calculated a total of {217503} coins issued for coin sets per denomination. Our own calculations found only {177003}. Numista also forgot to include the many hundred thousand coins from the coin roll sets that were produced.", + "translatorComment": "Copied from source.", + "placeholders": [ + { + "id": "217503", + "string": "%[1]d", + "type": "int", + "underlyingType": "int", + "argNum": 1, + "expr": "217503" + }, + { + "id": "177003", + "string": "%[2]d", + "type": "int", + "underlyingType": "int", + "argNum": 2, + "expr": "177003" + } + ], + "fuzzy": true + }, + { + "id": "Country", + "message": "Country", + "translation": "Country", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Circulation Coins", + "message": "Circulation Coins", + "translation": "Circulation Coins", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "NIFC / BU Sets", + "message": "NIFC / BU Sets", + "translation": "NIFC / BU Sets", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Proof Coins", + "message": "Proof Coins", + "translation": "Proof Coins", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Filter", + "message": "Filter", + "translation": "Filter", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Year", + "message": "Year", + "translation": "Year", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Unknown", + "message": "Unknown", + "translation": "Unknown", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Euro Coins", + "message": "Euro Coins", + "translation": "Euro Coins", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "On this section of the site you can find everything there is to know about the coins of the Eurozone. For the latest news on coin- and design releases, check out the {NewsLinkStart}news{LinkEnd} tab!", + "message": "On this section of the site you can find everything there is to know about the coins of the Eurozone. For the latest news on coin- and design releases, check out the {NewsLinkStart}news{LinkEnd} tab!", + "translation": "On this section of the site you can find everything there is to know about the coins of the Eurozone. For the latest news on coin- and design releases, check out the {NewsLinkStart}news{LinkEnd} tab!", + "translatorComment": "Copied from source.", + "placeholders": [ + { + "id": "NewsLinkStart", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "newsLinkStart" + }, + { + "id": "LinkEnd", + "string": "%[2]s", + "type": "string", + "underlyingType": "string", + "argNum": 2, + "expr": "linkEnd" + } + ], + "fuzzy": true + }, + { + "id": "Designs", + "message": "Designs", + "translation": "Designs", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "View the 600+ different Euro-coin designs!", + "message": "View the 600+ different Euro-coin designs!", + "translation": "View the 600+ different Euro-coin designs!", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Mintages", + "message": "Mintages", + "translation": "Mintages", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "View the mintage figures of all the Euro coins!", + "message": "View the mintage figures of all the Euro coins!", + "translation": "View the mintage figures of all the Euro coins!", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Varieties", + "message": "Varieties", + "translation": "Varieties", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "View all the known Euro varieties!", + "message": "View all the known Euro varieties!", + "translation": "View all the known Euro varieties!", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Select Your Language", + "message": "Select Your Language", + "translation": "Select Your Language", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Select your preferred language to use on the site.", + "message": "Select your preferred language to use on the site.", + "translation": "Select your preferred language to use on the site.", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Eurozone Languages", + "message": "Eurozone Languages", + "translation": "Eurozone Languages", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Other Languages", + "message": "Other Languages", + "translation": "Other Languages", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Home", + "message": "Home", + "translation": "Home", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "News", + "message": "News", + "translation": "News", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Coin Collecting", + "message": "Coin Collecting", + "translation": "Coin Collecting", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Coins", + "message": "Coins", + "translation": "Coins", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Banknotes", + "message": "Banknotes", + "translation": "Banknotes", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Jargon", + "message": "Jargon", + "translation": "Jargon", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Discord", + "message": "Discord", + "translation": "Discord", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "About", + "message": "About", + "translation": "About", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Language", + "message": "Language", + "translation": "Language", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "The Euro Cash Compendium", + "message": "The Euro Cash Compendium", + "translation": "The Euro Cash Compendium", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "United in", + "message": "United in", + "translation": "United in", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "diversity", + "message": "diversity", + "translation": "diversity", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "cash", + "message": "cash", + "translation": "cash", + "translatorComment": "Copied from source.", + "fuzzy": true + }, + { + "id": "Welcome to the Euro Cash Compendium. This sites aims to be a resource for you to discover everything there is to know about the coins and banknotes of the Euro, a currency that spans 26 countries and 350 million people. We also have dedicated sections of the site for collectors.", + "message": "Welcome to the Euro Cash Compendium. This sites aims to be a resource for you to discover everything there is to know about the coins and banknotes of the Euro, a currency that spans 26 countries and 350 million people. We also have dedicated sections of the site for collectors.", + "translation": "Welcome to the Euro Cash Compendium. This sites aims to be a resource for you to discover everything there is to know about the coins and banknotes of the Euro, a currency that spans 26 countries and 350 million people. We also have dedicated sections of the site for collectors.", + "translatorComment": "Copied from source.", + "fuzzy": true + } + ] +} \ No newline at end of file diff --git a/lib/locales/nl/messages.gotext.json b/lib/locales/nl/messages.gotext.json new file mode 100644 index 0000000..e3e8170 --- /dev/null +++ b/lib/locales/nl/messages.gotext.json @@ -0,0 +1,515 @@ +{ + "language": "nl", + "messages": [ + { + "id": "Page not found", + "message": "Page not found", + "translation": "" + }, + { + "id": "Andorra", + "message": "Andorra", + "translation": "Andorra" + }, + { + "id": "Austria", + "message": "Austria", + "translation": "Oostenrijk" + }, + { + "id": "Belgium", + "message": "Belgium", + "translation": "België" + }, + { + "id": "Cyprus", + "message": "Cyprus", + "translation": "Cyprus" + }, + { + "id": "Germany", + "message": "Germany", + "translation": "Duitsland" + }, + { + "id": "Estonia", + "message": "Estonia", + "translation": "Estland" + }, + { + "id": "Spain", + "message": "Spain", + "translation": "Spanje" + }, + { + "id": "Finland", + "message": "Finland", + "translation": "Finland" + }, + { + "id": "France", + "message": "France", + "translation": "Frankrijk" + }, + { + "id": "Greece", + "message": "Greece", + "translation": "Griekenland" + }, + { + "id": "Croatia", + "message": "Croatia", + "translation": "Kroatië" + }, + { + "id": "Ireland", + "message": "Ireland", + "translation": "Ierland" + }, + { + "id": "Italy", + "message": "Italy", + "translation": "Italië" + }, + { + "id": "Lithuania", + "message": "Lithuania", + "translation": "Litouwen" + }, + { + "id": "Luxembourg", + "message": "Luxembourg", + "translation": "Luxemburg" + }, + { + "id": "Latvia", + "message": "Latvia", + "translation": "Letland" + }, + { + "id": "Monaco", + "message": "Monaco", + "translation": "Monaco" + }, + { + "id": "Malta", + "message": "Malta", + "translation": "Malta" + }, + { + "id": "Netherlands", + "message": "Netherlands", + "translation": "Nederland" + }, + { + "id": "Portugal", + "message": "Portugal", + "translation": "Portugal" + }, + { + "id": "Slovenia", + "message": "Slovenia", + "translation": "Slovenië" + }, + { + "id": "Slovakia", + "message": "Slovakia", + "translation": "Slowakije" + }, + { + "id": "San Marino", + "message": "San Marino", + "translation": "San Marino" + }, + { + "id": "Vatican City", + "message": "Vatican City", + "translation": "Vaticaanstad" + }, + { + "id": "About Us", + "message": "About Us", + "translation": "" + }, + { + "id": "Open Source", + "message": "Open Source", + "translation": "" + }, + { + "id": "This website is an open project, and a collaboration between developers, translators, and researchers. All source code, data, images, and more for the website are open source and can be found {RepoLinkStart}here{LinkEnd}. This site is licensed under the BSD 0-Clause license giving you the full freedom to do whatever you would like with any of the content on this site.", + "message": "This website is an open project, and a collaboration between developers, translators, and researchers. All source code, data, images, and more for the website are open source and can be found {RepoLinkStart}here{LinkEnd}. This site is licensed under the BSD 0-Clause license giving you the full freedom to do whatever you would like with any of the content on this site.", + "translation": "", + "placeholders": [ + { + "id": "RepoLinkStart", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "repoLinkStart" + }, + { + "id": "LinkEnd", + "string": "%[2]s", + "type": "string", + "underlyingType": "string", + "argNum": 2, + "expr": "linkEnd" + } + ] + }, + { + "id": "Contact Us", + "message": "Contact Us", + "translation": "" + }, + { + "id": "While we try to stay as up-to-date as possible and to fact check our information, it is always possible that we get something wrong, lack a translation, or are missing some piece of data you may have. In such a case don’t hesitate to contact us; we’ll try to get the site updated or fixed as soon as possible. You are always free to contribute via a git patch if you are more technically included, but if not you can always send an email to {ContactEmail} or contact ‘@onetruemangoman’ on Discord.", + "message": "While we try to stay as up-to-date as possible and to fact check our information, it is always possible that we get something wrong, lack a translation, or are missing some piece of data you may have. In such a case don’t hesitate to contact us; we’ll try to get the site updated or fixed as soon as possible. You are always free to contribute via a git patch if you are more technically included, but if not you can always send an email to {ContactEmail} or contact ‘@onetruemangoman’ on Discord.", + "translation": "", + "placeholders": [ + { + "id": "ContactEmail", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "contactEmail" + } + ] + }, + { + "id": "Special Thanks", + "message": "Special Thanks", + "translation": "" + }, + { + "id": "Development", + "message": "Development", + "translation": "" + }, + { + "id": "Research", + "message": "Research", + "translation": "" + }, + { + "id": "Translations", + "message": "Translations", + "translation": "" + }, + { + "id": "British- \u0026 American English", + "message": "British- \u0026 American English", + "translation": "" + }, + { + "id": "Icelandic", + "message": "Icelandic", + "translation": "" + }, + { + "id": "Found a mistake or want to contribute missing information?", + "message": "Found a mistake or want to contribute missing information?", + "translation": "" + }, + { + "id": "Feel free to contact us!", + "message": "Feel free to contact us!", + "translation": "" + }, + { + "id": "Dutch Euro Coin Designs", + "message": "Dutch Euro Coin Designs", + "translation": "" + }, + { + "id": "From the years 1999–2013 all Dutch euro coins featured the portrait of Queen Beatrix of the Netherlands. After her abdication from the throne in 2013 the designs of all denominations were changed to feature the portrait of the new King Willem-Alexander. After her abdication the direction in which the monarchs portrait faced was flipped; a tradition dating back to the earliest coins of the Kingdom of the Netherlands.", + "message": "From the years 1999–2013 all Dutch euro coins featured the portrait of Queen Beatrix of the Netherlands. After her abdication from the throne in 2013 the designs of all denominations were changed to feature the portrait of the new King Willem-Alexander. After her abdication the direction in which the monarchs portrait faced was flipped; a tradition dating back to the earliest coins of the Kingdom of the Netherlands.", + "translation": "" + }, + { + "id": "Coins featuring both monarchs contain text reading ‘BEATRIX KONINGIN DER NEDERLANDEN’ (‘BEATRIX QUEEN OF THE NETHERLANDS’) and ‘Willem-Alexander Koning der Nederlanden’ (‘Willem-Alexander King of the Netherlands’) respectively.", + "message": "Coins featuring both monarchs contain text reading ‘BEATRIX KONINGIN DER NEDERLANDEN’ (‘BEATRIX QUEEN OF THE NETHERLANDS’) and ‘Willem-Alexander Koning der Nederlanden’ (‘Willem-Alexander King of the Netherlands’) respectively.", + "translation": "" + }, + { + "id": "The €1 and €2 coins featuring King Willem-Alexander were minted with a much lower relief than most euro coins of the same denomination. As a result it is not uncommon for these coins to appear worn after little use in circulation.", + "message": "The €1 and €2 coins featuring King Willem-Alexander were minted with a much lower relief than most euro coins of the same denomination. As a result it is not uncommon for these coins to appear worn after little use in circulation.", + "translation": "" + }, + { + "id": "Euro Coin Designs", + "message": "Euro Coin Designs", + "translation": "" + }, + { + "id": "Here you’ll be able to view all the coin designs for each country in the Eurozone. This section of the site doesn’t include minor varieties such as different mintmarks or errors; those are on the {VarietiesLinkStart}varieties{LinkEnd} page.", + "message": "Here you’ll be able to view all the coin designs for each country in the Eurozone. This section of the site doesn’t include minor varieties such as different mintmarks or errors; those are on the {VarietiesLinkStart}varieties{LinkEnd} page.", + "translation": "", + "placeholders": [ + { + "id": "VarietiesLinkStart", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "varietiesLinkStart" + }, + { + "id": "LinkEnd", + "string": "%[2]s", + "type": "string", + "underlyingType": "string", + "argNum": 2, + "expr": "linkEnd" + } + ] + }, + { + "id": "Euro Coin Mintages", + "message": "Euro Coin Mintages", + "translation": "" + }, + { + "id": "Here you’ll be able to view all the known mintages for all coins. You’ll also be able to filter on country, denomination, etc. If you have any mintage data that’s missing from our site, feel free to contact us.", + "message": "Here you’ll be able to view all the known mintages for all coins. You’ll also be able to filter on country, denomination, etc. If you have any mintage data that’s missing from our site, feel free to contact us.", + "translation": "" + }, + { + "id": "Additional Notes", + "message": "Additional Notes", + "translation": "" + }, + { + "id": "Most coins from the years 2003–2016 are listed as NIFC coins while other popular sources such as Numista claim they were minted for circulation. For more information on why others are wrong, {MuntrolpakketLinkStart}click here{LinkEnd}.", + "message": "Most coins from the years 2003–2016 are listed as NIFC coins while other popular sources such as Numista claim they were minted for circulation. For more information on why others are wrong, {MuntrolpakketLinkStart}click here{LinkEnd}.", + "translation": "", + "placeholders": [ + { + "id": "MuntrolpakketLinkStart", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "muntrolpakketLinkStart" + }, + { + "id": "LinkEnd", + "string": "%[2]s", + "type": "string", + "underlyingType": "string", + "argNum": 2, + "expr": "linkEnd" + } + ] + }, + { + "id": "In 2003 Numista calculated a total of {217503} coins issued for coin sets per denomination. Our own calculations found only {177003}. Numista also forgot to include the many hundred thousand coins from the coin roll sets that were produced.", + "message": "In 2003 Numista calculated a total of {217503} coins issued for coin sets per denomination. Our own calculations found only {177003}. Numista also forgot to include the many hundred thousand coins from the coin roll sets that were produced.", + "translation": "", + "placeholders": [ + { + "id": "217503", + "string": "%[1]d", + "type": "int", + "underlyingType": "int", + "argNum": 1, + "expr": "217503" + }, + { + "id": "177003", + "string": "%[2]d", + "type": "int", + "underlyingType": "int", + "argNum": 2, + "expr": "177003" + } + ] + }, + { + "id": "Country", + "message": "Country", + "translation": "" + }, + { + "id": "Circulation Coins", + "message": "Circulation Coins", + "translation": "" + }, + { + "id": "NIFC / BU Sets", + "message": "NIFC / BU Sets", + "translation": "" + }, + { + "id": "Proof Coins", + "message": "Proof Coins", + "translation": "" + }, + { + "id": "Filter", + "message": "Filter", + "translation": "" + }, + { + "id": "Year", + "message": "Year", + "translation": "" + }, + { + "id": "Unknown", + "message": "Unknown", + "translation": "" + }, + { + "id": "Euro Coins", + "message": "Euro Coins", + "translation": "" + }, + { + "id": "On this section of the site you can find everything there is to know about the coins of the Eurozone. For the latest news on coin- and design releases, check out the {NewsLinkStart}news{LinkEnd} tab!", + "message": "On this section of the site you can find everything there is to know about the coins of the Eurozone. For the latest news on coin- and design releases, check out the {NewsLinkStart}news{LinkEnd} tab!", + "translation": "", + "placeholders": [ + { + "id": "NewsLinkStart", + "string": "%[1]s", + "type": "string", + "underlyingType": "string", + "argNum": 1, + "expr": "newsLinkStart" + }, + { + "id": "LinkEnd", + "string": "%[2]s", + "type": "string", + "underlyingType": "string", + "argNum": 2, + "expr": "linkEnd" + } + ] + }, + { + "id": "Designs", + "message": "Designs", + "translation": "" + }, + { + "id": "View the 600+ different Euro-coin designs!", + "message": "View the 600+ different Euro-coin designs!", + "translation": "" + }, + { + "id": "Mintages", + "message": "Mintages", + "translation": "" + }, + { + "id": "View the mintage figures of all the Euro coins!", + "message": "View the mintage figures of all the Euro coins!", + "translation": "" + }, + { + "id": "Varieties", + "message": "Varieties", + "translation": "" + }, + { + "id": "View all the known Euro varieties!", + "message": "View all the known Euro varieties!", + "translation": "" + }, + { + "id": "Select Your Language", + "message": "Select Your Language", + "translation": "" + }, + { + "id": "Select your preferred language to use on the site.", + "message": "Select your preferred language to use on the site.", + "translation": "" + }, + { + "id": "Eurozone Languages", + "message": "Eurozone Languages", + "translation": "" + }, + { + "id": "Other Languages", + "message": "Other Languages", + "translation": "" + }, + { + "id": "Home", + "message": "Home", + "translation": "" + }, + { + "id": "News", + "message": "News", + "translation": "" + }, + { + "id": "Coin Collecting", + "message": "Coin Collecting", + "translation": "" + }, + { + "id": "Coins", + "message": "Coins", + "translation": "" + }, + { + "id": "Banknotes", + "message": "Banknotes", + "translation": "" + }, + { + "id": "Jargon", + "message": "Jargon", + "translation": "" + }, + { + "id": "Discord", + "message": "Discord", + "translation": "" + }, + { + "id": "About", + "message": "About", + "translation": "" + }, + { + "id": "Language", + "message": "Language", + "translation": "" + }, + { + "id": "The Euro Cash Compendium", + "message": "The Euro Cash Compendium", + "translation": "" + }, + { + "id": "United in", + "message": "United in", + "translation": "" + }, + { + "id": "diversity", + "message": "diversity", + "translation": "" + }, + { + "id": "cash", + "message": "cash", + "translation": "" + }, + { + "id": "Welcome to the Euro Cash Compendium. This sites aims to be a resource for you to discover everything there is to know about the coins and banknotes of the Euro, a currency that spans 26 countries and 350 million people. We also have dedicated sections of the site for collectors.", + "message": "Welcome to the Euro Cash Compendium. This sites aims to be a resource for you to discover everything there is to know about the coins and banknotes of the Euro, a currency that spans 26 countries and 350 million people. We also have dedicated sections of the site for collectors.", + "translation": "" + } + ] +} \ No newline at end of file diff --git a/lib/mintage/parser.go b/lib/mintage/parser.go new file mode 100644 index 0000000..4c5e6f9 --- /dev/null +++ b/lib/mintage/parser.go @@ -0,0 +1,207 @@ +package mintage + +import ( + "bufio" + "fmt" + "io" + "strconv" + "strings" + "unicode" +) + +const ( + _ = -iota + Unknown // Unknown mintage + Invalid // All mintages <= than this are invalid +) + +type SyntaxError struct { + expected, got string + file string + linenr int +} + +func (e SyntaxError) Error() string { + return fmt.Sprintf("%s:%d: syntax error: expected %s but got %s", + e.file, e.linenr, e.expected, e.got) +} + +type Row struct { + Year int + Mintmark string + Cols [8]int +} + +type Set struct { + StartYear int + Circ, BU, Proof []Row +} + +func (r Row) Label() string { + if r.Mintmark != "" { + return fmt.Sprintf("%d %s", r.Year, r.Mintmark) + } + return strconv.Itoa(r.Year) +} + +func Parse(reader io.Reader, file string) (Set, error) { + var ( + data Set // Our data struct + slice *[]Row // Where to append mintages + ) + + scanner := bufio.NewScanner(reader) + for linenr := 1; scanner.Scan(); linenr++ { + var mintmark struct { + s string + star bool + } + + line := scanner.Text() + tokens := strings.FieldsFunc(strings.TrimSpace(line), unicode.IsSpace) + + switch { + case len(tokens) == 0: + continue + case tokens[0] == "BEGIN": + if len(tokens)-1 != 1 { + return Set{}, SyntaxError{ + expected: "single argument to ‘BEGIN’", + got: fmt.Sprintf("%d arguments", len(tokens)-1), + file: file, + linenr: linenr, + } + } + + arg := tokens[1] + + switch arg { + case "CIRC": + slice = &data.Circ + case "BU": + slice = &data.BU + case "PROOF": + slice = &data.Proof + default: + if !isNumeric(arg, false) { + return Set{}, SyntaxError{ + expected: "‘CIRC’, ‘BU’, ‘PROOF’, or a year", + got: arg, + file: file, + linenr: linenr, + } + } + data.StartYear, _ = strconv.Atoi(arg) + } + case isLabel(tokens[0]): + n := len(tokens[0]) + if n > 2 && tokens[0][n-2] == '*' { + mintmark.star = true + mintmark.s = tokens[0][:n-2] + } else { + mintmark.s = tokens[0][:n-1] + } + tokens = tokens[1:] + if !isNumeric(tokens[0], true) && tokens[0] != "?" { + return Set{}, SyntaxError{ + expected: "mintage row after label", + got: tokens[0], + file: file, + linenr: linenr, + } + } + fallthrough + case isNumeric(tokens[0], true), tokens[0] == "?": + switch { + case slice == nil: + return Set{}, SyntaxError{ + expected: "coin type declaration", + got: tokens[0], + file: file, + linenr: linenr, + } + case data.StartYear == 0: + return Set{}, SyntaxError{ + expected: "start year declaration", + got: tokens[0], + file: file, + linenr: linenr, + } + } + + numcoins := len(Row{}.Cols) + tokcnt := len(tokens) + + if tokcnt != numcoins { + word := "entries" + if tokcnt == 1 { + word = "entry" + } + return Set{}, SyntaxError{ + expected: fmt.Sprintf("%d mintage entries", numcoins), + got: fmt.Sprintf("%d %s", tokcnt, word), + file: file, + linenr: linenr, + } + } + + row := Row{Mintmark: mintmark.s} + if len(*slice) == 0 { + row.Year = data.StartYear + } else { + row.Year = (*slice)[len(*slice)-1].Year + if row.Mintmark == "" || mintmark.star { + row.Year++ + } + } + + for i, tok := range tokens { + if tok == "?" { + row.Cols[i] = Unknown + } else { + row.Cols[i] = atoiWithDots(tok) + } + } + *slice = append(*slice, row) + default: + return Set{}, SyntaxError{ + expected: "‘BEGIN’ directive or mintage row", + got: fmt.Sprintf("invalid token ‘%s’", tokens[0]), + file: file, + linenr: linenr, + } + } + } + + return data, nil +} + +func isNumeric(s string, dot bool) bool { + for _, ch := range s { + switch ch { + case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': + default: + if ch != '.' || !dot { + return false + } + } + } + return true +} + +func isLabel(s string) bool { + n := len(s) + return (n > 2 && s[n-1] == ':' && s[n-2] == '*') || + (n > 1 && s[n-1] == ':') +} + +func atoiWithDots(s string) int { + n := 0 + for _, ch := range s { + if ch == '.' { + continue + } + n = n*10 + int(ch) - '0' + } + return n +} diff --git a/lib/mintage/parser_test.go b/lib/mintage/parser_test.go new file mode 100644 index 0000000..dd78c71 --- /dev/null +++ b/lib/mintage/parser_test.go @@ -0,0 +1,280 @@ +package mintage + +import ( + "bytes" + "errors" + "testing" +) + +func TestParserComplete(t *testing.T) { + data, err := Parse(bytes.NewBuffer([]byte(` + BEGIN 2020 + BEGIN CIRC + 1.000 1001 1002 1003 1004 1005 1006 1007 + 2000 ? 2002 2003 2004 2005 2006 2007 + BEGIN BU + 1.100 1101 1102 1103 1104 1105 1106 1107 + 2100 ? 2102 2103 2104 2105 2106 2107 + BEGIN PROOF + 1.200 1201 1202 1203 1204 1205 1206 1207 + 2200 ? 2202 2203 2204 2205 2206 2207 + `)), "-") + + if err != nil { + t.Fatalf(`Expected err=nil; got "%s"`, err) + } + if data.StartYear != 2020 { + t.Fatalf("Expected data.StartYear=2020; got %d", + data.StartYear) + } + + for i, row := range data.Circ { + for j, col := range row.Cols { + var n int + if i == 1 && j == 1 { + n = -1 + } else { + n = 1000*i + j + 1000 + } + if col != n { + t.Fatalf("Expected data.Circ[i][j]=%d; got %d", n, col) + } + } + } + + for i, row := range data.BU { + for j, col := range row.Cols { + var n int + if i == 1 && j == 1 { + n = -1 + } else { + n = 1000*i + j + 1100 + } + if col != n { + t.Fatalf("Expected data.BU[i][j]=%d; got %d", n, col) + } + } + } + + for i, row := range data.Proof { + for j, col := range row.Cols { + var n int + if i == 1 && j == 1 { + n = -1 + } else { + n = 1000*i + j + 1200 + } + if col != n { + t.Fatalf("Expected data.Proof[i][j]=%d; got %d", n, col) + } + } + } + + if len(data.Circ) != 2 { + t.Fatalf("Expected len(data.Circ)=2; got %d", len(data.Circ)) + } + if len(data.BU) != 2 { + t.Fatalf("Expected len(data.BU)=2; got %d", len(data.BU)) + } + if len(data.Proof) != 2 { + t.Fatalf("Expected len(data.Proof)=2; got %d", len(data.Proof)) + } +} + +func TestParserNoProof(t *testing.T) { + data, err := Parse(bytes.NewBuffer([]byte(` + BEGIN 2020 + BEGIN CIRC + 1.000 1001 1002 1003 1004 1005 1006 1007 + 2000 ? 2002 2003 2004 2005 2006 2007 + BEGIN BU + 1.100 1101 1102 1103 1104 1105 1106 1107 + 2100 ? 2102 2103 2104 2105 2106 2107 + `)), "-") + + if err != nil { + t.Fatalf(`Expected err=nil; got "%s"`, err) + } + + if len(data.Proof) != 0 { + t.Fatalf("Expected len(data.Proof)=0; got %d", len(data.Proof)) + } +} + +func TestParserMintmarks(t *testing.T) { + data, err := Parse(bytes.NewBuffer([]byte(` + BEGIN 2020 + BEGIN CIRC + 1.000 1001 1002 1003 1004 1005 1006 1007 + KNM*: 2000 ? 2002 2003 2004 2005 2006 2007 + MdP: 3000 ? 3002 3003 3004 3005 3006 3007 + `)), "-") + + if err != nil { + t.Fatalf(`Expected err=nil; got "%s"`, err) + } + + for i, row := range data.Circ { + for j, col := range row.Cols { + var n int + if i > 0 && j == 1 { + n = -1 + } else { + n = 1000*i + j + 1000 + } + if col != n { + t.Fatalf("Expected data.Circ[i][j]=%d; got %d", n, col) + } + } + } + + for i, y := range [...]int{2020, 2021, 2021} { + if data.Circ[i].Year != y { + t.Fatalf("Expected data.Circ[%d].Year=%d; got %d", + i, y, data.Circ[i].Year) + } + } + for i, s := range [...]string{"", "KNM", "MdP"} { + if data.Circ[i].Mintmark != s { + t.Fatalf(`Expected data.Circ[%d].Mintmark="%s"; got "%s"`, + i, s, data.Circ[i].Mintmark) + } + } +} + +func TestParserNoYear(t *testing.T) { + _, err := Parse(bytes.NewBuffer([]byte(` + BEGIN CIRC + 1.000 1001 1002 1003 1004 1005 1006 1007 + 2000 ? 2002 2003 2004 2005 2006 2007 + BEGIN BU + 1.100 1101 1102 1103 1104 1105 1106 1107 + 2100 ? 2102 2103 2104 2105 2106 2107 + BEGIN PROOF + 1.200 1201 1202 1203 1204 1205 1206 1207 + 2200 ? 2202 2203 2204 2205 2206 2207 + `)), "-") + + var sErr SyntaxError + if !errors.As(err, &sErr) { + t.Fatalf("Expected err=SyntaxError; got %s", err) + } +} + +func TestParserNoType(t *testing.T) { + _, err := Parse(bytes.NewBuffer([]byte(` + BEGIN 2020 + 1.000 1001 1002 1003 1004 1005 1006 1007 + 2000 ? 2002 2003 2004 2005 2006 2007 + BEGIN BU + 1.100 1101 1102 1103 1104 1105 1106 1107 + 2100 ? 2102 2103 2104 2105 2106 2107 + BEGIN PROOF + 1.200 1201 1202 1203 1204 1205 1206 1207 + 2200 ? 2202 2203 2204 2205 2206 2207 + `)), "-") + + var sErr SyntaxError + if !errors.As(err, &sErr) { + t.Fatalf("Expected err=SyntaxError; got %s", err) + } +} + +func TestParserNoYearOrType(t *testing.T) { + _, err := Parse(bytes.NewBuffer([]byte(` + 1.000 1001 1002 1003 1004 1005 1006 1007 + 2000 ? 2002 2003 2004 2005 2006 2007 + BEGIN BU + 1.100 1101 1102 1103 1104 1105 1106 1107 + 2100 ? 2102 2103 2104 2105 2106 2107 + BEGIN PROOF + 1.200 1201 1202 1203 1204 1205 1206 1207 + 2200 ? 2202 2203 2204 2205 2206 2207 + `)), "-") + + var sErr SyntaxError + if !errors.As(err, &sErr) { + t.Fatalf("Expected err=SyntaxError; got %s", err) + } +} + +func TestParserBadToken(t *testing.T) { + _, err := Parse(bytes.NewBuffer([]byte(` + BEGIN 2020 + BEGIN CIRC + 1.000 1001 1002 1003 1004 1005 1006 1007 + I’m bad + 2000 ? 2002 2003 2004 2005 2006 2007 + BEGIN BU + 1.100 1101 1102 1103 1104 1105 1106 1107 + 2100 ? 2102 2103 2104 2105 2106 2107 + BEGIN PROOF + 1.200 1201 1202 1203 1204 1205 1206 1207 + 2200 ? 2202 2203 2204 2205 2206 2207 + `)), "-") + + var sErr SyntaxError + if !errors.As(err, &sErr) { + t.Fatalf("Expected err=SyntaxError; got %s", err) + } +} + +func TestParserShortRow(t *testing.T) { + _, err := Parse(bytes.NewBuffer([]byte(` + BEGIN 2020 + BEGIN CIRC + 1.000 1001 1002 1003 1004 1005 1006 1007 + 2000 ? 2002 2003 2004 2005 2006 2007 + BEGIN BU + 1.100 1101 1102 1103 1104 1105 1106 1107 + 2100 ? 2102 2103 2104 2105 2106 + BEGIN PROOF + 1.200 1201 1202 1203 1204 1205 1206 1207 + 2200 ? 2202 2203 2204 2205 2206 2207 + `)), "-") + + var sErr SyntaxError + if !errors.As(err, &sErr) { + t.Fatalf("Expected err=SyntaxError; got %s", err) + } +} + +func TestParserLongRow(t *testing.T) { + _, err := Parse(bytes.NewBuffer([]byte(` + BEGIN 2020 + BEGIN CIRC + 1.000 1001 1002 1003 1004 1005 1006 1007 + 2000 ? 2002 2003 2004 2005 2006 2007 + BEGIN BU + 1.100 1101 1102 1103 1104 1105 1106 1107 + 2100 ? 2102 2103 2104 2105 2106 2107 2108 + BEGIN PROOF + 1.200 1201 1202 1203 1204 1205 1206 1207 + 2200 ? 2202 2203 2204 2205 2206 2207 + `)), "-") + + var sErr SyntaxError + if !errors.As(err, &sErr) { + t.Fatalf("Expected err=SyntaxError; got %s", err) + } +} + +func TestParserBadCoinType(t *testing.T) { + _, err := Parse(bytes.NewBuffer([]byte(` + BEGIN 2020 + BEGIN CIRCULATED + 1.000 1001 1002 1003 1004 1005 1006 1007 + 2000 ? 2002 2003 2004 2005 2006 2007 + BEGIN BU + 1.100 1101 1102 1103 1104 1105 1106 1107 + 2100 ? 2102 2103 2104 2105 2106 2107 + BEGIN PROOF + 1.200 1201 1202 1203 1204 1205 1206 1207 + 2200 ? 2202 2203 2204 2205 2206 2207 + `)), "-") + + var sErr SyntaxError + if !errors.As(err, &sErr) { + t.Fatalf("Expected err=SyntaxError; got %s", err) + } +} diff --git a/main.go b/main.go index e0c73e6..21a3b1a 100644 --- a/main.go +++ b/main.go @@ -2,32 +2,36 @@ package main import ( "cmp" + "context" "errors" "flag" "fmt" "log" "math" "net/http" + "os" + "path/filepath" "strconv" "strings" - "git.thomasvoss.com/euro-cash.eu/i18n" - "git.thomasvoss.com/euro-cash.eu/middleware" - "git.thomasvoss.com/euro-cash.eu/templates" + "git.thomasvoss.com/euro-cash.eu/lib" + "git.thomasvoss.com/euro-cash.eu/lib/mintage" + "git.thomasvoss.com/euro-cash.eu/template" "github.com/a-h/templ" ) var components = map[string]templ.Component{ - "/": templates.Root(), - "/about": templates.About(), - "/coins": templates.Coins(), - "/coins/designs": templates.CoinsDesigns(), - "/coins/designs/nl": templates.CoinsDesignsNl(), - "/language": templates.Language(), + "/": template.Root(), + "/about": template.About(), + "/coins": template.Coins(), + "/coins/designs": template.CoinsDesigns(), + "/coins/designs/nl": template.CoinsDesignsNl(), + "/coins/mintages": template.CoinsMintages(), + "/language": template.Language(), } func main() { - i18n.InitPrinters() + lib.InitPrinters() port := flag.Int("port", 8080, "port number") flag.Parse() @@ -38,7 +42,8 @@ func main() { mux.Handle("GET /favicon.ico", fs) mux.Handle("GET /fonts/", fs) mux.Handle("GET /style.css", fs) - mux.Handle("GET /", middleware.I18n(http.HandlerFunc(finalHandler))) + mux.Handle("GET /coins/mintages", i18nHandler(mintageHandler(http.HandlerFunc(finalHandler)))) + mux.Handle("GET /", i18nHandler(http.HandlerFunc(finalHandler))) mux.Handle("POST /language", http.HandlerFunc(setUserLanguage)) portStr := ":" + strconv.Itoa(*port) @@ -47,7 +52,7 @@ func main() { } func finalHandler(w http.ResponseWriter, r *http.Request) { - p := r.Context().Value("printer").(i18n.Printer) + p := r.Context().Value("printer").(lib.Printer) /* Strip trailing slash from the URL */ path := r.URL.Path @@ -69,15 +74,62 @@ func finalHandler(w http.ResponseWriter, r *http.Request) { Value: cmp.Or(r.Referer(), "/"), }) } - templates.Base(nil, c).Render(r.Context(), w) + template.Base(c).Render(r.Context(), w) } } +func i18nHandler(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + var p, pZero lib.Printer + + if c, err := r.Cookie("locale"); errors.Is(err, http.ErrNoCookie) { + log.Println("Language cookie not set") + } else { + var ok bool + p, ok = lib.Printers[strings.ToLower(c.Value)] + if !ok { + log.Printf("Language ‘%s’ is unsupported\n", c.Value) + } + } + + ctx := context.WithValue( + r.Context(), "printer", cmp.Or(p, lib.DefaultPrinter)) + + if p == pZero { + http.SetCookie(w, &http.Cookie{ + Name: "redirect", + Value: r.URL.Path, + }) + template.Base(template.Language()).Render(ctx, w) + } else { + next.ServeHTTP(w, r.WithContext(ctx)) + } + }) +} + +func mintageHandler(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + countries := lib.SortedCountries( + r.Context().Value("printer").(lib.Printer)) + code := cmp.Or(r.FormValue("c"), countries[0].Code) + + path := filepath.Join("data", "mintages", code) + f, _ := os.Open(path) // TODO: Handle error + defer f.Close() + set, _ := mintage.Parse(f, path) // TODO: Handle error + + ctx := context.WithValue(r.Context(), "code", code) + ctx = context.WithValue(ctx, "set", set) + ctx = context.WithValue(ctx, "countries", countries) + next.ServeHTTP(w, r.WithContext(ctx)) + }) +} + func setUserLanguage(w http.ResponseWriter, r *http.Request) { loc := r.FormValue("locale") - _, ok := i18n.Printers[strings.ToLower(loc)] + _, ok := lib.Printers[strings.ToLower(loc)] if !ok { - w.WriteHeader(http.StatusBadRequest) + w.WriteHeader(http.StatusUnprocessableEntity) fmt.Fprintf(w, "Locale ‘%s’ is invalid or unsupported", loc) return } diff --git a/middleware/i18n.go b/middleware/i18n.go deleted file mode 100644 index 921534e..0000000 --- a/middleware/i18n.go +++ /dev/null @@ -1,42 +0,0 @@ -package middleware - -import ( - "cmp" - "context" - "errors" - "log" - "net/http" - "strings" - - "git.thomasvoss.com/euro-cash.eu/i18n" - "git.thomasvoss.com/euro-cash.eu/templates" -) - -func I18n(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - var p, pZero i18n.Printer - - if c, err := r.Cookie("locale"); errors.Is(err, http.ErrNoCookie) { - log.Println("Language cookie not set") - } else { - var ok bool - p, ok = i18n.Printers[strings.ToLower(c.Value)] - if !ok { - log.Printf("Language ‘%s’ is unsupported\n", c.Value) - } - } - - ctx := context.WithValue( - r.Context(), "printer", cmp.Or(p, i18n.DefaultPrinter)) - - if p == pZero { - http.SetCookie(w, &http.Cookie{ - Name: "redirect", - Value: r.URL.Path, - }) - templates.Base(nil, templates.Language()).Render(ctx, w) - } else { - next.ServeHTTP(w, r.WithContext(ctx)) - } - }) -} diff --git a/mintage/parser.go b/mintage/parser.go deleted file mode 100644 index 4c5e6f9..0000000 --- a/mintage/parser.go +++ /dev/null @@ -1,207 +0,0 @@ -package mintage - -import ( - "bufio" - "fmt" - "io" - "strconv" - "strings" - "unicode" -) - -const ( - _ = -iota - Unknown // Unknown mintage - Invalid // All mintages <= than this are invalid -) - -type SyntaxError struct { - expected, got string - file string - linenr int -} - -func (e SyntaxError) Error() string { - return fmt.Sprintf("%s:%d: syntax error: expected %s but got %s", - e.file, e.linenr, e.expected, e.got) -} - -type Row struct { - Year int - Mintmark string - Cols [8]int -} - -type Set struct { - StartYear int - Circ, BU, Proof []Row -} - -func (r Row) Label() string { - if r.Mintmark != "" { - return fmt.Sprintf("%d %s", r.Year, r.Mintmark) - } - return strconv.Itoa(r.Year) -} - -func Parse(reader io.Reader, file string) (Set, error) { - var ( - data Set // Our data struct - slice *[]Row // Where to append mintages - ) - - scanner := bufio.NewScanner(reader) - for linenr := 1; scanner.Scan(); linenr++ { - var mintmark struct { - s string - star bool - } - - line := scanner.Text() - tokens := strings.FieldsFunc(strings.TrimSpace(line), unicode.IsSpace) - - switch { - case len(tokens) == 0: - continue - case tokens[0] == "BEGIN": - if len(tokens)-1 != 1 { - return Set{}, SyntaxError{ - expected: "single argument to ‘BEGIN’", - got: fmt.Sprintf("%d arguments", len(tokens)-1), - file: file, - linenr: linenr, - } - } - - arg := tokens[1] - - switch arg { - case "CIRC": - slice = &data.Circ - case "BU": - slice = &data.BU - case "PROOF": - slice = &data.Proof - default: - if !isNumeric(arg, false) { - return Set{}, SyntaxError{ - expected: "‘CIRC’, ‘BU’, ‘PROOF’, or a year", - got: arg, - file: file, - linenr: linenr, - } - } - data.StartYear, _ = strconv.Atoi(arg) - } - case isLabel(tokens[0]): - n := len(tokens[0]) - if n > 2 && tokens[0][n-2] == '*' { - mintmark.star = true - mintmark.s = tokens[0][:n-2] - } else { - mintmark.s = tokens[0][:n-1] - } - tokens = tokens[1:] - if !isNumeric(tokens[0], true) && tokens[0] != "?" { - return Set{}, SyntaxError{ - expected: "mintage row after label", - got: tokens[0], - file: file, - linenr: linenr, - } - } - fallthrough - case isNumeric(tokens[0], true), tokens[0] == "?": - switch { - case slice == nil: - return Set{}, SyntaxError{ - expected: "coin type declaration", - got: tokens[0], - file: file, - linenr: linenr, - } - case data.StartYear == 0: - return Set{}, SyntaxError{ - expected: "start year declaration", - got: tokens[0], - file: file, - linenr: linenr, - } - } - - numcoins := len(Row{}.Cols) - tokcnt := len(tokens) - - if tokcnt != numcoins { - word := "entries" - if tokcnt == 1 { - word = "entry" - } - return Set{}, SyntaxError{ - expected: fmt.Sprintf("%d mintage entries", numcoins), - got: fmt.Sprintf("%d %s", tokcnt, word), - file: file, - linenr: linenr, - } - } - - row := Row{Mintmark: mintmark.s} - if len(*slice) == 0 { - row.Year = data.StartYear - } else { - row.Year = (*slice)[len(*slice)-1].Year - if row.Mintmark == "" || mintmark.star { - row.Year++ - } - } - - for i, tok := range tokens { - if tok == "?" { - row.Cols[i] = Unknown - } else { - row.Cols[i] = atoiWithDots(tok) - } - } - *slice = append(*slice, row) - default: - return Set{}, SyntaxError{ - expected: "‘BEGIN’ directive or mintage row", - got: fmt.Sprintf("invalid token ‘%s’", tokens[0]), - file: file, - linenr: linenr, - } - } - } - - return data, nil -} - -func isNumeric(s string, dot bool) bool { - for _, ch := range s { - switch ch { - case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': - default: - if ch != '.' || !dot { - return false - } - } - } - return true -} - -func isLabel(s string) bool { - n := len(s) - return (n > 2 && s[n-1] == ':' && s[n-2] == '*') || - (n > 1 && s[n-1] == ':') -} - -func atoiWithDots(s string) int { - n := 0 - for _, ch := range s { - if ch == '.' { - continue - } - n = n*10 + int(ch) - '0' - } - return n -} diff --git a/mintage/parser_test.go b/mintage/parser_test.go deleted file mode 100644 index dd78c71..0000000 --- a/mintage/parser_test.go +++ /dev/null @@ -1,280 +0,0 @@ -package mintage - -import ( - "bytes" - "errors" - "testing" -) - -func TestParserComplete(t *testing.T) { - data, err := Parse(bytes.NewBuffer([]byte(` - BEGIN 2020 - BEGIN CIRC - 1.000 1001 1002 1003 1004 1005 1006 1007 - 2000 ? 2002 2003 2004 2005 2006 2007 - BEGIN BU - 1.100 1101 1102 1103 1104 1105 1106 1107 - 2100 ? 2102 2103 2104 2105 2106 2107 - BEGIN PROOF - 1.200 1201 1202 1203 1204 1205 1206 1207 - 2200 ? 2202 2203 2204 2205 2206 2207 - `)), "-") - - if err != nil { - t.Fatalf(`Expected err=nil; got "%s"`, err) - } - if data.StartYear != 2020 { - t.Fatalf("Expected data.StartYear=2020; got %d", - data.StartYear) - } - - for i, row := range data.Circ { - for j, col := range row.Cols { - var n int - if i == 1 && j == 1 { - n = -1 - } else { - n = 1000*i + j + 1000 - } - if col != n { - t.Fatalf("Expected data.Circ[i][j]=%d; got %d", n, col) - } - } - } - - for i, row := range data.BU { - for j, col := range row.Cols { - var n int - if i == 1 && j == 1 { - n = -1 - } else { - n = 1000*i + j + 1100 - } - if col != n { - t.Fatalf("Expected data.BU[i][j]=%d; got %d", n, col) - } - } - } - - for i, row := range data.Proof { - for j, col := range row.Cols { - var n int - if i == 1 && j == 1 { - n = -1 - } else { - n = 1000*i + j + 1200 - } - if col != n { - t.Fatalf("Expected data.Proof[i][j]=%d; got %d", n, col) - } - } - } - - if len(data.Circ) != 2 { - t.Fatalf("Expected len(data.Circ)=2; got %d", len(data.Circ)) - } - if len(data.BU) != 2 { - t.Fatalf("Expected len(data.BU)=2; got %d", len(data.BU)) - } - if len(data.Proof) != 2 { - t.Fatalf("Expected len(data.Proof)=2; got %d", len(data.Proof)) - } -} - -func TestParserNoProof(t *testing.T) { - data, err := Parse(bytes.NewBuffer([]byte(` - BEGIN 2020 - BEGIN CIRC - 1.000 1001 1002 1003 1004 1005 1006 1007 - 2000 ? 2002 2003 2004 2005 2006 2007 - BEGIN BU - 1.100 1101 1102 1103 1104 1105 1106 1107 - 2100 ? 2102 2103 2104 2105 2106 2107 - `)), "-") - - if err != nil { - t.Fatalf(`Expected err=nil; got "%s"`, err) - } - - if len(data.Proof) != 0 { - t.Fatalf("Expected len(data.Proof)=0; got %d", len(data.Proof)) - } -} - -func TestParserMintmarks(t *testing.T) { - data, err := Parse(bytes.NewBuffer([]byte(` - BEGIN 2020 - BEGIN CIRC - 1.000 1001 1002 1003 1004 1005 1006 1007 - KNM*: 2000 ? 2002 2003 2004 2005 2006 2007 - MdP: 3000 ? 3002 3003 3004 3005 3006 3007 - `)), "-") - - if err != nil { - t.Fatalf(`Expected err=nil; got "%s"`, err) - } - - for i, row := range data.Circ { - for j, col := range row.Cols { - var n int - if i > 0 && j == 1 { - n = -1 - } else { - n = 1000*i + j + 1000 - } - if col != n { - t.Fatalf("Expected data.Circ[i][j]=%d; got %d", n, col) - } - } - } - - for i, y := range [...]int{2020, 2021, 2021} { - if data.Circ[i].Year != y { - t.Fatalf("Expected data.Circ[%d].Year=%d; got %d", - i, y, data.Circ[i].Year) - } - } - for i, s := range [...]string{"", "KNM", "MdP"} { - if data.Circ[i].Mintmark != s { - t.Fatalf(`Expected data.Circ[%d].Mintmark="%s"; got "%s"`, - i, s, data.Circ[i].Mintmark) - } - } -} - -func TestParserNoYear(t *testing.T) { - _, err := Parse(bytes.NewBuffer([]byte(` - BEGIN CIRC - 1.000 1001 1002 1003 1004 1005 1006 1007 - 2000 ? 2002 2003 2004 2005 2006 2007 - BEGIN BU - 1.100 1101 1102 1103 1104 1105 1106 1107 - 2100 ? 2102 2103 2104 2105 2106 2107 - BEGIN PROOF - 1.200 1201 1202 1203 1204 1205 1206 1207 - 2200 ? 2202 2203 2204 2205 2206 2207 - `)), "-") - - var sErr SyntaxError - if !errors.As(err, &sErr) { - t.Fatalf("Expected err=SyntaxError; got %s", err) - } -} - -func TestParserNoType(t *testing.T) { - _, err := Parse(bytes.NewBuffer([]byte(` - BEGIN 2020 - 1.000 1001 1002 1003 1004 1005 1006 1007 - 2000 ? 2002 2003 2004 2005 2006 2007 - BEGIN BU - 1.100 1101 1102 1103 1104 1105 1106 1107 - 2100 ? 2102 2103 2104 2105 2106 2107 - BEGIN PROOF - 1.200 1201 1202 1203 1204 1205 1206 1207 - 2200 ? 2202 2203 2204 2205 2206 2207 - `)), "-") - - var sErr SyntaxError - if !errors.As(err, &sErr) { - t.Fatalf("Expected err=SyntaxError; got %s", err) - } -} - -func TestParserNoYearOrType(t *testing.T) { - _, err := Parse(bytes.NewBuffer([]byte(` - 1.000 1001 1002 1003 1004 1005 1006 1007 - 2000 ? 2002 2003 2004 2005 2006 2007 - BEGIN BU - 1.100 1101 1102 1103 1104 1105 1106 1107 - 2100 ? 2102 2103 2104 2105 2106 2107 - BEGIN PROOF - 1.200 1201 1202 1203 1204 1205 1206 1207 - 2200 ? 2202 2203 2204 2205 2206 2207 - `)), "-") - - var sErr SyntaxError - if !errors.As(err, &sErr) { - t.Fatalf("Expected err=SyntaxError; got %s", err) - } -} - -func TestParserBadToken(t *testing.T) { - _, err := Parse(bytes.NewBuffer([]byte(` - BEGIN 2020 - BEGIN CIRC - 1.000 1001 1002 1003 1004 1005 1006 1007 - I’m bad - 2000 ? 2002 2003 2004 2005 2006 2007 - BEGIN BU - 1.100 1101 1102 1103 1104 1105 1106 1107 - 2100 ? 2102 2103 2104 2105 2106 2107 - BEGIN PROOF - 1.200 1201 1202 1203 1204 1205 1206 1207 - 2200 ? 2202 2203 2204 2205 2206 2207 - `)), "-") - - var sErr SyntaxError - if !errors.As(err, &sErr) { - t.Fatalf("Expected err=SyntaxError; got %s", err) - } -} - -func TestParserShortRow(t *testing.T) { - _, err := Parse(bytes.NewBuffer([]byte(` - BEGIN 2020 - BEGIN CIRC - 1.000 1001 1002 1003 1004 1005 1006 1007 - 2000 ? 2002 2003 2004 2005 2006 2007 - BEGIN BU - 1.100 1101 1102 1103 1104 1105 1106 1107 - 2100 ? 2102 2103 2104 2105 2106 - BEGIN PROOF - 1.200 1201 1202 1203 1204 1205 1206 1207 - 2200 ? 2202 2203 2204 2205 2206 2207 - `)), "-") - - var sErr SyntaxError - if !errors.As(err, &sErr) { - t.Fatalf("Expected err=SyntaxError; got %s", err) - } -} - -func TestParserLongRow(t *testing.T) { - _, err := Parse(bytes.NewBuffer([]byte(` - BEGIN 2020 - BEGIN CIRC - 1.000 1001 1002 1003 1004 1005 1006 1007 - 2000 ? 2002 2003 2004 2005 2006 2007 - BEGIN BU - 1.100 1101 1102 1103 1104 1105 1106 1107 - 2100 ? 2102 2103 2104 2105 2106 2107 2108 - BEGIN PROOF - 1.200 1201 1202 1203 1204 1205 1206 1207 - 2200 ? 2202 2203 2204 2205 2206 2207 - `)), "-") - - var sErr SyntaxError - if !errors.As(err, &sErr) { - t.Fatalf("Expected err=SyntaxError; got %s", err) - } -} - -func TestParserBadCoinType(t *testing.T) { - _, err := Parse(bytes.NewBuffer([]byte(` - BEGIN 2020 - BEGIN CIRCULATED - 1.000 1001 1002 1003 1004 1005 1006 1007 - 2000 ? 2002 2003 2004 2005 2006 2007 - BEGIN BU - 1.100 1101 1102 1103 1104 1105 1106 1107 - 2100 ? 2102 2103 2104 2105 2106 2107 - BEGIN PROOF - 1.200 1201 1202 1203 1204 1205 1206 1207 - 2200 ? 2202 2203 2204 2205 2206 2207 - `)), "-") - - var sErr SyntaxError - if !errors.As(err, &sErr) { - t.Fatalf("Expected err=SyntaxError; got %s", err) - } -} diff --git a/template/about.templ b/template/about.templ new file mode 100644 index 0000000..d7dfa06 --- /dev/null +++ b/template/about.templ @@ -0,0 +1,52 @@ +package template + +import "git.thomasvoss.com/euro-cash.eu/lib" + +const ( + contactEmail = `mail@euro-cash.eu` + repoLinkStart = `` + linkEnd = `` +) + +templ About() { + {{ p := ctx.Value("printer").(lib.Printer) }} +
+ @navbar() +

{ p.T("About Us") }

+
+
+

{ p.T("Open Source") }

+

+ @templ.Raw(p.T("This website is an open project, and a collaboration between developers, translators, and researchers. All source code, data, images, and more for the website are open source and can be found %shere%s. This site is licensed under the BSD 0-Clause license giving you the full freedom to do whatever you would like with any of the content on this site.", repoLinkStart, linkEnd)) +

+

{ p.T("Contact Us") }

+

+ @templ.Raw(p.T("While we try to stay as up-to-date as possible and to fact check our information, it is always possible that we get something wrong, lack a translation, or are missing some piece of data you may have. In such a case don’t hesitate to contact us; we’ll try to get the site updated or fixed as soon as possible. You are always free to contribute via a git patch if you are more technically included, but if not you can always send an email to %s or contact ‘@onetruemangoman’ on Discord.", contactEmail)) +

+

{ p.T("Special Thanks") }

+ + + + + + + + + + + + + +
{ p.T("Development") }{ p.T("Research") }{ p.T("Translations") }
+ Jessika Wexler, + Lyyli Savolainen, + Ralf Nadel + + Elín Hjartardóttir, + Storm Sørensen + + Thomas Voss, + Védís Indriðadóttir +
+
+} diff --git a/template/base.go b/template/base.go new file mode 100644 index 0000000..392b1c2 --- /dev/null +++ b/template/base.go @@ -0,0 +1,3 @@ +//go:generate templ generate -log-level warn + +package template diff --git a/template/base.templ b/template/base.templ new file mode 100644 index 0000000..bd8c082 --- /dev/null +++ b/template/base.templ @@ -0,0 +1,51 @@ +package template + +import "git.thomasvoss.com/euro-cash.eu/lib" + +templ Base(body templ.Component) { + {{ p := ctx.Value("printer").(lib.Printer) }} + + + + + + + Euro Cash + + + + @body + + + +} diff --git a/template/coins.templ b/template/coins.templ new file mode 100644 index 0000000..ef1b0a1 --- /dev/null +++ b/template/coins.templ @@ -0,0 +1,53 @@ +package template + +import "git.thomasvoss.com/euro-cash.eu/lib" + +const newsLinkStart = `` + +templ Coins() { + {{ p := ctx.Value("printer").(lib.Printer) }} +
+ @navbar() +

{ p.T("Euro Coins") }

+
+
+

+ @templ.Raw(p.T("On this section of the site you can find everything there is to know about the coins of the Eurozone. For the latest news on coin- and design releases, check out the %snews%s tab!", newsLinkStart, linkEnd)) +

+
+
+ +
+
+} diff --git a/template/coins_designs.templ b/template/coins_designs.templ new file mode 100644 index 0000000..de47482 --- /dev/null +++ b/template/coins_designs.templ @@ -0,0 +1,41 @@ +package template + +import ( + "fmt" + "strings" + + "git.thomasvoss.com/euro-cash.eu/lib" +) + +var varietiesLinkStart = `` + +func makeURL(c lib.Country) templ.SafeURL { + url := fmt.Sprintf("/coins/designs/%s", c.Code) + return templ.SafeURL(url) +} + +templ CoinsDesigns() { + {{ p := ctx.Value("printer").(lib.Printer) }} +
+ @navbar() +

{ p.T("Euro Coin Designs") }

+
+
+

+ @templ.Raw(p.T("Here you’ll be able to view all the coin designs for each country in the Eurozone. This section of the site doesn’t include minor varieties such as different mintmarks or errors; those are on the %svarieties%s page.", varietiesLinkStart, linkEnd)) +

+
+
+
+} diff --git a/template/coins_designs_nl.templ b/template/coins_designs_nl.templ new file mode 100644 index 0000000..819b294 --- /dev/null +++ b/template/coins_designs_nl.templ @@ -0,0 +1,43 @@ +package template + +import "git.thomasvoss.com/euro-cash.eu/lib" + +templ CoinsDesignsNl() { + {{ p := ctx.Value("printer").(lib.Printer) }} +
+ @navbar() +

{ p.T("Dutch Euro Coin Designs") }

+
+
+
+ Netherlands Queen Beatrix €0.50 Coin + Netherlands King Willem-Alexander €0.50 Coin +
+
+ Netherlands Queen Beatrix €1 Coin + Netherlands King Willem-Alexander €1 Coin +
+

+ { p.T("From the years 1999–2013 all Dutch euro coins featured the portrait of Queen Beatrix of the Netherlands. After her abdication from the throne in 2013 the designs of all denominations were changed to feature the portrait of the new King Willem-Alexander. After her abdication the direction in which the monarchs portrait faced was flipped; a tradition dating back to the earliest coins of the Kingdom of the Netherlands.") } +

+

+ { p.T("Coins featuring both monarchs contain text reading ‘BEATRIX KONINGIN DER NEDERLANDEN’ (‘BEATRIX QUEEN OF THE NETHERLANDS’) and ‘Willem-Alexander Koning der Nederlanden’ (‘Willem-Alexander King of the Netherlands’) respectively.") } +

+

+ + { p.T("The €1 and €2 coins featuring King Willem-Alexander were minted with a much lower relief than most euro coins of the same denomination. As a result it is not uncommon for these coins to appear worn after little use in circulation.") } +

+
+} diff --git a/template/coins_mintages.templ b/template/coins_mintages.templ new file mode 100644 index 0000000..b6ed2de --- /dev/null +++ b/template/coins_mintages.templ @@ -0,0 +1,112 @@ +package template + +import ( + "strconv" + + "git.thomasvoss.com/euro-cash.eu/lib" + "git.thomasvoss.com/euro-cash.eu/lib/mintage" +) + +const muntrolpakketLinkStart = `` + +var denoms = [...]float64{ + 0.01, 0.02, 0.05, 0.10, + 0.20, 0.50, 1.00, 2.00, +} + +templ CoinsMintages() { + {{ + code := ctx.Value("code").(string) + set := ctx.Value("set").(mintage.Set) + p := ctx.Value("printer").(lib.Printer) + }} +
+ @navbar() +

{ p.T("Euro Coin Mintages") }

+
+
+

+ { p.T("Here you’ll be able to view all the known mintages for all coins. You’ll also be able to filter on country, denomination, etc. If you have any mintage data that’s missing from our site, feel free to contact us.") } +

+
+ if code == "nl" { +

{ p.T("Additional Notes") }

+
    +
  • + @templ.Raw(p.T("Most coins from the years 2003–2016 are listed as NIFC coins while other popular sources such as Numista claim they were minted for circulation. For more information on why others are wrong, %sclick here%s.", muntrolpakketLinkStart, linkEnd)) +
  • +
  • + { p.T("In 2003 Numista calculated a total of %d coins issued for coin sets per denomination. Our own calculations found only %d. Numista also forgot to include the many hundred thousand coins from the coin roll sets that were produced.", 217503, 177003) } +
  • +
+ } +
+
+
+ +
+ + + +
+
+ +
+
+ + + + for _, x := range denoms { + + } + + + for _, row := range set.Circ { + + + for _, col := range row.Cols { + switch col { + case mintage.Unknown: + + case 0: + + default: + + } + } + + } + +
{ p.T("Year") }{ p.Money(x, false) }
+ if row.Mintmark != "" { + { strconv.Itoa(row.Year) } { row.Mintmark } + } else { + { strconv.Itoa(row.Year) } + } + { p.T("Unknown") }{ p.N(col) }
+
+
+
+} diff --git a/template/language.templ b/template/language.templ new file mode 100644 index 0000000..1b48295 --- /dev/null +++ b/template/language.templ @@ -0,0 +1,54 @@ +package template + +import ( + "strings" + + "git.thomasvoss.com/euro-cash.eu/lib" +) + +templ Language() { + {{ p := ctx.Value("printer").(lib.Printer) }} +
+ @navbar() +

{ p.T("Select Your Language") }

+
+
+

+ { p.T("Select your preferred language to use on the site.") } +

+

+ If you are an American user, it’s suggested that you select + American English instead of British English. This will ensure that + dates will be formatted with the month before the day. +

+
+

{ p.T("Eurozone Languages") }

+ @languageGrid(true) +

{ p.T("Other Languages") }

+ @languageGrid(false) +
+} + +templ languageGrid(eurozone bool) { +
+
+ for _, loc := range lib.Locales { + if loc.Eurozone == eurozone { + + } + } +
+
+} diff --git a/template/navbar.templ b/template/navbar.templ new file mode 100644 index 0000000..2aceac2 --- /dev/null +++ b/template/navbar.templ @@ -0,0 +1,241 @@ +package template + +import "git.thomasvoss.com/euro-cash.eu/lib" + +templ navbar() { + {{ p := ctx.Value("printer").(lib.Printer) }} +
+} + +css noMargin() { + margin: 0; +} diff --git a/template/root.templ b/template/root.templ new file mode 100644 index 0000000..657314c --- /dev/null +++ b/template/root.templ @@ -0,0 +1,23 @@ +package template + +import "git.thomasvoss.com/euro-cash.eu/lib" + +templ Root() { + {{ p := ctx.Value("printer").(lib.Printer) }} +
+ @navbar() +
+

{ p.T("The Euro Cash Compendium") }

+

+ { p.T("United in") } + { p.T("diversity") } + { p.T("cash") } +

+
+
+
+

+ { p.T("Welcome to the Euro Cash Compendium. This sites aims to be a resource for you to discover everything there is to know about the coins and banknotes of the Euro, a currency that spans 26 countries and 350 million people. We also have dedicated sections of the site for collectors.") } +

+
+} diff --git a/templates/about.templ b/templates/about.templ deleted file mode 100644 index 8add2dd..0000000 --- a/templates/about.templ +++ /dev/null @@ -1,52 +0,0 @@ -package templates - -import "git.thomasvoss.com/euro-cash.eu/i18n" - -const ( - contactEmail = `mail@euro-cash.eu` - repoLinkStart = `` - linkEnd = `` -) - -templ About() { - {{ p := ctx.Value("printer").(i18n.Printer) }} -
- @navbar() -

{ p.T("About Us") }

-
-
-

{ p.T("Open Source") }

-

- @templ.Raw(p.T("This website is an open project, and a collaboration between developers, translators, and researchers. All source code, data, images, and more for the website are open source and can be found %shere%s. This site is licensed under the BSD 0-Clause license giving you the full freedom to do whatever you would like with any of the content on this site.", repoLinkStart, linkEnd)) -

-

{ p.T("Contact Us") }

-

- @templ.Raw(p.T("While we try to stay as up-to-date as possible and to fact check our information, it is always possible that we get something wrong, lack a translation, or are missing some piece of data you may have. In such a case don’t hesitate to contact us; we’ll try to get the site updated or fixed as soon as possible. You are always free to contribute via a git patch if you are more technically included, but if not you can always send an email to %s or contact ‘@onetruemangoman’ on Discord.", contactEmail)) -

-

{ p.T("Special Thanks") }

- - - - - - - - - - - - - -
{ p.T("Development") }{ p.T("Research") }{ p.T("Translations") }
- Jessika Wexler, - Lyyli Savolainen, - Ralf Nadel - - Elín Hjartardóttir, - Storm Sørensen - - Thomas Voss, - Védís Indriðadóttir -
-
-} diff --git a/templates/base.go b/templates/base.go deleted file mode 100644 index 76a4da6..0000000 --- a/templates/base.go +++ /dev/null @@ -1,63 +0,0 @@ -//go:generate templ generate -log-level warn - -package templates - -import ( - "fmt" - "slices" - - "git.thomasvoss.com/euro-cash.eu/i18n" - "golang.org/x/text/collate" - "golang.org/x/text/language" -) - -type country struct { - code, name string -} - -type sortType int - -const ( - sortByCode sortType = iota - sortByName -) - -func countries(p i18n.Printer, sort sortType) []country { - xs := []country{ - {code: "AD", name: p.T("Andorra")}, - {code: "AT", name: p.T("Austria")}, - {code: "BE", name: p.T("Belgium")}, - {code: "CY", name: p.T("Cyprus")}, - {code: "DE", name: p.T("Germany")}, - {code: "EE", name: p.T("Estonia")}, - {code: "ES", name: p.T("Spain")}, - {code: "FI", name: p.T("Finland")}, - {code: "FR", name: p.T("France")}, - {code: "GR", name: p.T("Greece")}, - {code: "HR", name: p.T("Croatia")}, - {code: "IE", name: p.T("Ireland")}, - {code: "IT", name: p.T("Italy")}, - {code: "LT", name: p.T("Lithuania")}, - {code: "LU", name: p.T("Luxembourg")}, - {code: "LV", name: p.T("Latvia")}, - {code: "MC", name: p.T("Monaco")}, - {code: "MT", name: p.T("Malta")}, - {code: "NL", name: p.T("Netherlands")}, - {code: "PT", name: p.T("Portugal")}, - {code: "SI", name: p.T("Slovenia")}, - {code: "SK", name: p.T("Slovakia")}, - {code: "SM", name: p.T("San Marino")}, - {code: "VA", name: p.T("Vatican City")}, - } - switch sort { - case sortByCode: - case sortByName: - c := collate.New(language.MustParse(p.Locale.Bcp)) - slices.SortFunc(xs, func(x, y country) int { - return c.CompareString(x.name, y.name) - }) - default: - panic(fmt.Sprintf("Attempted to sort by invalid sortType=%d", sort)) - } - return xs -} diff --git a/templates/base.templ b/templates/base.templ deleted file mode 100644 index e6c4a1d..0000000 --- a/templates/base.templ +++ /dev/null @@ -1,59 +0,0 @@ -package templates - -import "git.thomasvoss.com/euro-cash.eu/i18n" - -templ Base(head, body templ.Component) { - {{ p := ctx.Value("printer").(i18n.Printer) }} - - - - - - - Euro Cash - - if head != nil { - @head - } - - - if body != nil { - @body - } - - - -} diff --git a/templates/coins.templ b/templates/coins.templ deleted file mode 100644 index 050d7e8..0000000 --- a/templates/coins.templ +++ /dev/null @@ -1,53 +0,0 @@ -package templates - -import "git.thomasvoss.com/euro-cash.eu/i18n" - -const newsLinkStart = `` - -templ Coins() { - {{ p := ctx.Value("printer").(i18n.Printer) }} -
- @navbar() -

{ p.T("Euro Coins") }

-
-
-

- @templ.Raw(p.T("On this section of the site you can find everything there is to know about the coins of the Eurozone. For the latest news on coin- and design releases, check out the %snews%s tab!", newsLinkStart, linkEnd)) -

-
-
- -
-
-} diff --git a/templates/coins_designs.templ b/templates/coins_designs.templ deleted file mode 100644 index 4732ab0..0000000 --- a/templates/coins_designs.templ +++ /dev/null @@ -1,41 +0,0 @@ -package templates - -import ( - "fmt" - "strings" - - "git.thomasvoss.com/euro-cash.eu/i18n" -) - -var varietiesLinkStart = `` - -func makeURL(c country) templ.SafeURL { - url := fmt.Sprintf("/coins/designs/%s", strings.ToLower(c.code)) - return templ.SafeURL(url) -} - -templ CoinsDesigns() { - {{ p := ctx.Value("printer").(i18n.Printer) }} -
- @navbar() -

{ p.T("Euro Coin Designs") }

-
-
-

- @templ.Raw(p.T("Here you’ll be able to view all the coin designs for each country in the Eurozone. This section of the site doesn’t include minor varieties such as different mintmarks or errors; those are on the %svarieties%s page.", varietiesLinkStart, linkEnd)) -

-
-
-
-} diff --git a/templates/coins_designs_nl.templ b/templates/coins_designs_nl.templ deleted file mode 100644 index d0d82da..0000000 --- a/templates/coins_designs_nl.templ +++ /dev/null @@ -1,43 +0,0 @@ -package templates - -import "git.thomasvoss.com/euro-cash.eu/i18n" - -templ CoinsDesignsNl() { - {{ p := ctx.Value("printer").(i18n.Printer) }} -
- @navbar() -

{ p.T("Dutch Euro Coin Designs") }

-
-
-
- Netherlands Queen Beatrix €0.50 Coin - Netherlands King Willem-Alexander €0.50 Coin -
-
- Netherlands Queen Beatrix €1 Coin - Netherlands King Willem-Alexander €1 Coin -
-

- { p.T("From the years 1999–2013 all Dutch euro coins featured the portrait of Queen Beatrix of the Netherlands. After her abdication from the throne in 2013 the designs of all denominations were changed to feature the portrait of the new King Willem-Alexander. After her abdication the direction in which the monarchs portrait faced was flipped; a tradition dating back to the earliest coins of the Kingdom of the Netherlands.") } -

-

- { p.T("Coins featuring both monarchs contain text reading ‘BEATRIX KONINGIN DER NEDERLANDEN’ (‘BEATRIX QUEEN OF THE NETHERLANDS’) and ‘Willem-Alexander Koning der Nederlanden’ (‘Willem-Alexander King of the Netherlands’) respectively.") } -

-

- - { p.T("The €1 and €2 coins featuring King Willem-Alexander were minted with a much lower relief than most euro coins of the same denomination. As a result it is not uncommon for these coins to appear worn after little use in circulation.") } -

-
-} diff --git a/templates/language.templ b/templates/language.templ deleted file mode 100644 index 58dc8b6..0000000 --- a/templates/language.templ +++ /dev/null @@ -1,54 +0,0 @@ -package templates - -import ( - "strings" - - "git.thomasvoss.com/euro-cash.eu/i18n" -) - -templ Language() { - {{ p := ctx.Value("printer").(i18n.Printer) }} -
- @navbar() -

{ p.T("Select Your Language") }

-
-
-

- { p.T("Select your preferred language to use on the site.") } -

-

- If you are an American user, it’s suggested that you select - American English instead of British English. This will ensure that - dates will be formatted with the month before the day. -

-
-

{ p.T("Eurozone Languages") }

- @languageGrid(true) -

{ p.T("Other Languages") }

- @languageGrid(false) -
-} - -templ languageGrid(eurozone bool) { -
-
- for _, loc := range i18n.Locales { - if loc.Eurozone == eurozone { - - } - } -
-
-} diff --git a/templates/navbar.templ b/templates/navbar.templ deleted file mode 100644 index f0b030c..0000000 --- a/templates/navbar.templ +++ /dev/null @@ -1,241 +0,0 @@ -package templates - -import "git.thomasvoss.com/euro-cash.eu/i18n" - -templ navbar() { - {{ p := ctx.Value("printer").(i18n.Printer) }} - -} - -css noMargin() { - margin: 0; -} diff --git a/templates/root.templ b/templates/root.templ deleted file mode 100644 index bfe9210..0000000 --- a/templates/root.templ +++ /dev/null @@ -1,23 +0,0 @@ -package templates - -import "git.thomasvoss.com/euro-cash.eu/i18n" - -templ Root() { - {{ p := ctx.Value("printer").(i18n.Printer) }} -
- @navbar() -
-

{ p.T("The Euro Cash Compendium") }

-

- { p.T("United in") } - { p.T("diversity") } - { p.T("cash") } -

-
-
-
-

- { p.T("Welcome to the Euro Cash Compendium. This sites aims to be a resource for you to discover everything there is to know about the coins and banknotes of the Euro, a currency that spans 26 countries and 350 million people. We also have dedicated sections of the site for collectors.") } -

-
-} -- cgit v1.2.3