From 0d88c7e878c52e3c12e3e561c96d9e7a759960a7 Mon Sep 17 00:00:00 2001 From: kjon Date: Fri, 28 Jul 2023 06:08:58 +0000 Subject: [PATCH 1/9] Translated using Weblate (German) Currently translated at 100.0% (502 of 502 strings) Translation: MapComplete/Core Translate-URL: https://hosted.weblate.org/projects/mapcomplete/core/de/ --- langs/de.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/langs/de.json b/langs/de.json index 2995ce4dd2..ff399a2cdc 100644 --- a/langs/de.json +++ b/langs/de.json @@ -14,7 +14,7 @@ "available": "Diese Gemeinschaft spricht {native}", "intro": "Treten Sie mit anderen Menschen in Kontakt, um sie kennen zu lernen, von ihnen zu lernen, …", "notAvailable": "Diese Gemeinschaft spricht nicht {native}", - "title": "Index der Community" + "title": "Mit anderen in Kontakt treten" }, "delete": { "cancel": "Abbrechen", From fb290777902b120de1c70415838444ff9b0e3e3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Allan=20Nordh=C3=B8y?= Date: Thu, 27 Jul 2023 23:40:10 +0000 Subject: [PATCH 2/9] =?UTF-8?q?Translated=20using=20Weblate=20(Norwegian?= =?UTF-8?q?=20Bokm=C3=A5l)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently translated at 64.3% (323 of 502 strings) Translation: MapComplete/Core Translate-URL: https://hosted.weblate.org/projects/mapcomplete/core/nb_NO/ --- langs/nb_NO.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/langs/nb_NO.json b/langs/nb_NO.json index de0ede216a..7856c11fbe 100644 --- a/langs/nb_NO.json +++ b/langs/nb_NO.json @@ -1,4 +1,7 @@ { + "advanced": { + "title": "Avanserte funksjoner" + }, "centerMessage": { "loadingData": "Laster inn data …", "ready": "Ferdig", From 91089072391cef7867f67eece44eecfe02f79ed5 Mon Sep 17 00:00:00 2001 From: kjon Date: Fri, 28 Jul 2023 06:10:20 +0000 Subject: [PATCH 3/9] Translated using Weblate (German) Currently translated at 100.0% (3054 of 3054 strings) Translation: MapComplete/Layer translations Translate-URL: https://hosted.weblate.org/projects/mapcomplete/layers/de/ --- langs/layers/de.json | 537 +++++++++++++++++++++++-------------------- 1 file changed, 288 insertions(+), 249 deletions(-) diff --git a/langs/layers/de.json b/langs/layers/de.json index 4d9dab1380..c8b2bf68c0 100644 --- a/langs/layers/de.json +++ b/langs/layers/de.json @@ -35,6 +35,16 @@ "1": { "title": "eine freistehende Posterbox" }, + "10": { + "description": "Verwendet für Werbeschilder, Leuchtreklamen, Logos und institutionelle Eingangsschilder", + "title": "ein Schild" + }, + "11": { + "title": "eine Skulptur" + }, + "12": { + "title": "eine Wandmalerei" + }, "2": { "title": "eine wandmontierte Posterbox" }, @@ -61,16 +71,6 @@ }, "9": { "title": "ein Totem" - }, - "10": { - "description": "Verwendet für Werbeschilder, Leuchtreklamen, Logos und institutionelle Eingangsschilder", - "title": "ein Schild" - }, - "11": { - "title": "eine Skulptur" - }, - "12": { - "title": "eine Wandmalerei" } }, "tagRenderings": { @@ -165,6 +165,9 @@ "1": { "then": "Dies ist ein Brett" }, + "10": { + "then": "Dies ist eine Wandmalerei" + }, "2": { "then": "Dies ist eine Litfaßsäule" }, @@ -188,9 +191,6 @@ }, "9": { "then": "Dies ist ein Totem" - }, - "10": { - "then": "Dies ist eine Wandmalerei" } }, "question": "Welche Art von Werbung ist das?", @@ -205,6 +205,9 @@ "1": { "then": "Brett" }, + "10": { + "then": "Wandmalerei" + }, "2": { "then": "Posterbox" }, @@ -228,9 +231,6 @@ }, "9": { "then": "Totem" - }, - "10": { - "then": "Wandmalerei" } } } @@ -312,6 +312,15 @@ "1": { "then": "Wandbild" }, + "10": { + "then": "Azulejo (spanische dekorative Fliesenarbeit)" + }, + "11": { + "then": "Fliesenarbeit" + }, + "12": { + "then": "Holzschnitzerei" + }, "2": { "then": "Malerei" }, @@ -335,15 +344,6 @@ }, "9": { "then": "Relief" - }, - "10": { - "then": "Azulejo (spanische dekorative Fliesenarbeit)" - }, - "11": { - "then": "Fliesenarbeit" - }, - "12": { - "then": "Holzschnitzerei" } }, "question": "Um welche Art Kunstwerk handelt es sich?", @@ -1830,6 +1830,27 @@ "1": { "question": "Verfügt über einen
Schuko-Stecker ohne Erdungsstift (CEE7/4 Typ F)
" }, + "10": { + "question": "Hat einen
Typ 2 (Mennekes)
Anschluss mit Kabel" + }, + "11": { + "question": "Hat einen
Tesla Supercharger CCS (Typ 2 CSS vonTesla)
Anschluss" + }, + "12": { + "question": "Hat einen
Tesla Supercharger (Destination)
Anschluss" + }, + "13": { + "question": "Hat einen
Tesla Supercharger (Destination) (Typ 2 von Tesla)
Anschluss mit Kabel" + }, + "14": { + "question": "Hat einen
USB-Anschluss zum Aufladen von Telefonen und kleinen Elektrogeräten
" + }, + "15": { + "question": "Hat einen
Bosch Active Connect Anschluss mit 3 Pins
und Kabel" + }, + "16": { + "question": "Hat einen
Bosch Active Connect Anschluss mit 5 Pins
und Kabel" + }, "2": { "question": "Verfügt über einen
europäischen Netzstecker mit Erdungsstift (CEE7/4 Typ E)
Anschluss" }, @@ -1853,27 +1874,6 @@ }, "9": { "question": "Hat einen
Typ 2 CCS (Mennekes)
Anschluss" - }, - "10": { - "question": "Hat einen
Typ 2 (Mennekes)
Anschluss mit Kabel" - }, - "11": { - "question": "Hat einen
Tesla Supercharger CCS (Typ 2 CSS vonTesla)
Anschluss" - }, - "12": { - "question": "Hat einen
Tesla Supercharger (Destination)
Anschluss" - }, - "13": { - "question": "Hat einen
Tesla Supercharger (Destination) (Typ 2 von Tesla)
Anschluss mit Kabel" - }, - "14": { - "question": "Hat einen
USB-Anschluss zum Aufladen von Telefonen und kleinen Elektrogeräten
" - }, - "15": { - "question": "Hat einen
Bosch Active Connect Anschluss mit 3 Pins
und Kabel" - }, - "16": { - "question": "Hat einen
Bosch Active Connect Anschluss mit 5 Pins
und Kabel" } } } @@ -1929,30 +1929,6 @@ "1": { "then": "Schuko-Stecker ohne Erdungsstift (CEE7/4 Typ F)" }, - "2": { - "then": "Europäischer Netzstecker mit Erdungsstift (CEE7/4 Typ E)" - }, - "3": { - "then": "Europäischer Netzstecker mit Erdungsstift (CEE7/4 Typ E)" - }, - "4": { - "then": "Chademo-Anschluss" - }, - "5": { - "then": "Chademo-Anschluss" - }, - "6": { - "then": "Typ 1 mit Kabel (J1772)" - }, - "7": { - "then": "Typ 1 mit Kabel (J1772)" - }, - "8": { - "then": "Typ 1 ohne Kabel (J1772)" - }, - "9": { - "then": " Typ 1 ohne Kabel (J1772)" - }, "10": { "then": "Typ 1 CCS (Typ 1 Combo)" }, @@ -1983,6 +1959,9 @@ "19": { "then": "Typ 2 mit Kabel (mennekes)" }, + "2": { + "then": "Europäischer Netzstecker mit Erdungsstift (CEE7/4 Typ E)" + }, "20": { "then": "Tesla Supercharger CCS (Typ 2 CSS von Tesla)" }, @@ -2013,11 +1992,32 @@ "29": { "then": " Bosch Active Connect mit 3 Pins und Kabel" }, + "3": { + "then": "Europäischer Netzstecker mit Erdungsstift (CEE7/4 Typ E)" + }, "30": { "then": "Bosch Active Connect mit 5 Pins und Kabel" }, "31": { "then": " Bosch Active Connect mit 5 Pins und Kabel" + }, + "4": { + "then": "Chademo-Anschluss" + }, + "5": { + "then": "Chademo-Anschluss" + }, + "6": { + "then": "Typ 1 mit Kabel (J1772)" + }, + "7": { + "then": "Typ 1 mit Kabel (J1772)" + }, + "8": { + "then": "Typ 1 ohne Kabel (J1772)" + }, + "9": { + "then": " Typ 1 ohne Kabel (J1772)" } }, "question": "Welche Ladeanschlüsse gibt es hier?" @@ -3555,6 +3555,15 @@ "1": { "then": "Dieser Radweg hat einen festen Belag" }, + "10": { + "then": "Dieser Radweg besteht aus feinem Schotter" + }, + "11": { + "then": "Der Radweg ist aus Kies" + }, + "12": { + "then": "Dieser Radweg besteht aus Rohboden" + }, "2": { "then": "Der Radweg ist aus Asphalt" }, @@ -3578,15 +3587,6 @@ }, "9": { "then": "Der Radweg ist aus Schotter" - }, - "10": { - "then": "Dieser Radweg besteht aus feinem Schotter" - }, - "11": { - "then": "Der Radweg ist aus Kies" - }, - "12": { - "then": "Dieser Radweg besteht aus Rohboden" } }, "question": "Was ist der Belag dieses Radwegs?", @@ -3635,6 +3635,15 @@ "1": { "then": "Dieser Radweg hat einen festen Belag" }, + "10": { + "then": "Dieser Radweg besteht aus feinem Schotter" + }, + "11": { + "then": "Der Radweg ist aus Kies" + }, + "12": { + "then": "Dieser Radweg besteht aus Rohboden" + }, "2": { "then": "Der Radweg ist aus Asphalt" }, @@ -3658,15 +3667,6 @@ }, "9": { "then": "Der Radweg ist aus Schotter" - }, - "10": { - "then": "Dieser Radweg besteht aus feinem Schotter" - }, - "11": { - "then": "Der Radweg ist aus Kies" - }, - "12": { - "then": "Dieser Radweg besteht aus Rohboden" } }, "question": "Was ist der Belag dieser Straße?", @@ -4606,30 +4606,6 @@ "1": { "then": "Die Fitness-Station hat ein Schild mit Anweisungen für eine bestimmte Übung." }, - "2": { - "then": "Die Fitness-Station hat eine Einrichtung für Sit-ups." - }, - "3": { - "then": "Die Fitness-Station hat eine Vorrichtung für Liegestütze. In der Regel eine oder mehrere niedrige Reckstangen." - }, - "4": { - "then": "Die Fitness-Station hat Stangen zum Dehnen." - }, - "5": { - "then": "Die Fitness-Station hat eine Vorrichtung für Rückenstrecker (Hyperextensions)." - }, - "6": { - "then": "Die Fitness-Station hat Ringe für Gymnastikübungen." - }, - "7": { - "then": "Die Fitness-Station hat eine horizontale Leiter (Monkey Bars)." - }, - "8": { - "then": "Die Fitness-Station hat eine Sprossenwand zum Klettern." - }, - "9": { - "then": "Die Fitness-Station hat Pfosten für Slalomübungen." - }, "10": { "then": "Die Fitness-Station hat Trittsteine." }, @@ -4660,6 +4636,9 @@ "19": { "then": "Die Fitness-Station hat Kampfseile (battle ropes)." }, + "2": { + "then": "Die Fitness-Station hat eine Einrichtung für Sit-ups." + }, "20": { "then": "Die Fitness-Station hat ein Fahrradergometer." }, @@ -4674,6 +4653,27 @@ }, "24": { "then": "Die Fitness-Station hat eine Slackline." + }, + "3": { + "then": "Die Fitness-Station hat eine Vorrichtung für Liegestütze. In der Regel eine oder mehrere niedrige Reckstangen." + }, + "4": { + "then": "Die Fitness-Station hat Stangen zum Dehnen." + }, + "5": { + "then": "Die Fitness-Station hat eine Vorrichtung für Rückenstrecker (Hyperextensions)." + }, + "6": { + "then": "Die Fitness-Station hat Ringe für Gymnastikübungen." + }, + "7": { + "then": "Die Fitness-Station hat eine horizontale Leiter (Monkey Bars)." + }, + "8": { + "then": "Die Fitness-Station hat eine Sprossenwand zum Klettern." + }, + "9": { + "then": "Die Fitness-Station hat Pfosten für Slalomübungen." } }, "question": "Welche Übungsgeräte gibt es an dieser Fitness-Station?" @@ -4780,6 +4780,21 @@ "1": { "then": "Dies ist eine Pommesbude" }, + "10": { + "then": "Hier werden chinesische Gerichte serviert" + }, + "11": { + "then": "Hier werden griechische Gerichte serviert" + }, + "12": { + "then": "Hier werden indische Gerichte serviert" + }, + "13": { + "then": "Hier werden türkische Gerichte serviert" + }, + "14": { + "then": "Hier werden thailändische Gerichte serviert" + }, "2": { "then": "Bietet vorwiegend Pastagerichte an" }, @@ -4803,21 +4818,6 @@ }, "9": { "then": "Hier werden französische Gerichte serviert" - }, - "10": { - "then": "Hier werden chinesische Gerichte serviert" - }, - "11": { - "then": "Hier werden griechische Gerichte serviert" - }, - "12": { - "then": "Hier werden indische Gerichte serviert" - }, - "13": { - "then": "Hier werden türkische Gerichte serviert" - }, - "14": { - "then": "Hier werden thailändische Gerichte serviert" } }, "question": "Was für Essen gibt es hier?", @@ -6036,6 +6036,19 @@ } } }, + "10": { + "options": { + "0": { + "question": "Alle Notizen" + }, + "1": { + "question": "Importnotizen ausblenden" + }, + "2": { + "question": "Nur Importnotizen anzeigen" + } + } + }, "2": { "options": { "0": { @@ -6091,19 +6104,6 @@ "question": "Nur offene Notizen anzeigen" } } - }, - "10": { - "options": { - "0": { - "question": "Alle Notizen" - }, - "1": { - "question": "Importnotizen ausblenden" - }, - "2": { - "question": "Nur Importnotizen anzeigen" - } - } } }, "name": "OpenStreetMap-Hinweise", @@ -6432,6 +6432,21 @@ "1": { "then": "Dies ist ein normaler Stellplatz." }, + "10": { + "then": "Dies ist ein Stellplatz, der für Eltern mit Kindern reserviert ist." + }, + "11": { + "then": "Dies ist ein Stellplatz, der für das Personal reserviert ist." + }, + "12": { + "then": "Dies ist ein Stellplatz, der für Taxis reserviert ist." + }, + "13": { + "then": "Dies ist ein Stellplatz, der für Fahrzeuge mit Anhänger reserviert ist." + }, + "14": { + "then": "Dies ist ein Stellplatz, der für Carsharing reserviert ist." + }, "2": { "then": "Dies ist ein Behindertenstellplatz." }, @@ -6455,21 +6470,6 @@ }, "9": { "then": "Dies ist ein Stellplatz, der für Motorräder reserviert ist." - }, - "10": { - "then": "Dies ist ein Stellplatz, der für Eltern mit Kindern reserviert ist." - }, - "11": { - "then": "Dies ist ein Stellplatz, der für das Personal reserviert ist." - }, - "12": { - "then": "Dies ist ein Stellplatz, der für Taxis reserviert ist." - }, - "13": { - "then": "Dies ist ein Stellplatz, der für Fahrzeuge mit Anhänger reserviert ist." - }, - "14": { - "then": "Dies ist ein Stellplatz, der für Carsharing reserviert ist." } }, "question": "Welche Art von Stellplatz ist dies?" @@ -7318,6 +7318,15 @@ }, "question": "Ist das Rauchen in {title()} erlaubt?" }, + "survey_date": { + "mappings": { + "0": { + "then": "Dieses Objekt wurde heute zuletzt geprüft" + } + }, + "question": "Wann wurde dieses Objekt zuletzt geprüft?", + "render": "Dieses Objekt wurde zuletzt geprüft am {survey:date}" + }, "website": { "question": "Wie lautet die Webseite von {title()}?" }, @@ -7443,30 +7452,6 @@ "1": { "question": "Recycling von Batterien" }, - "2": { - "question": "Recycling von Getränkekartons" - }, - "3": { - "question": "Recycling von Dosen" - }, - "4": { - "question": "Recycling von Kleidung" - }, - "5": { - "question": "Recycling von Speiseöl" - }, - "6": { - "question": "Recycling von Motoröl" - }, - "7": { - "question": "Recycling von Leuchtstoffröhren" - }, - "8": { - "question": "Recycling von Grünabfällen" - }, - "9": { - "question": "Recycling von Glasflaschen" - }, "10": { "question": "Recycling von Glas" }, @@ -7497,11 +7482,35 @@ "19": { "question": "Recycling von Restabfällen" }, + "2": { + "question": "Recycling von Getränkekartons" + }, "20": { "question": "Recycling von Druckerpatronen" }, "21": { "question": "Recycling von Fahrrädern" + }, + "3": { + "question": "Recycling von Dosen" + }, + "4": { + "question": "Recycling von Kleidung" + }, + "5": { + "question": "Recycling von Speiseöl" + }, + "6": { + "question": "Recycling von Motoröl" + }, + "7": { + "question": "Recycling von Leuchtstoffröhren" + }, + "8": { + "question": "Recycling von Grünabfällen" + }, + "9": { + "question": "Recycling von Glasflaschen" } } }, @@ -7569,30 +7578,6 @@ "1": { "then": "Getränkekartons können hier recycelt werden" }, - "2": { - "then": "Dosen können hier recycelt werden" - }, - "3": { - "then": "Kleidung kann hier recycelt werden" - }, - "4": { - "then": "Speiseöl kann hier recycelt werden" - }, - "5": { - "then": "Motoröl kann hier recycelt werden" - }, - "6": { - "then": "Hier können Leuchtstoffröhren recycelt werden" - }, - "7": { - "then": "Grünabfälle können hier recycelt werden" - }, - "8": { - "then": "Bio-Abfall kann hier recycelt werden" - }, - "9": { - "then": "Glasflaschen können hier recycelt werden" - }, "10": { "then": "Glas kann hier recycelt werden" }, @@ -7623,6 +7608,9 @@ "19": { "then": "Schuhe können hier recycelt werden" }, + "2": { + "then": "Dosen können hier recycelt werden" + }, "20": { "then": "Elektrokleingeräte können hier recycelt werden" }, @@ -7637,6 +7625,27 @@ }, "24": { "then": "Fahrräder können hier recycelt werden" + }, + "3": { + "then": "Kleidung kann hier recycelt werden" + }, + "4": { + "then": "Speiseöl kann hier recycelt werden" + }, + "5": { + "then": "Motoröl kann hier recycelt werden" + }, + "6": { + "then": "Hier können Leuchtstoffröhren recycelt werden" + }, + "7": { + "then": "Grünabfälle können hier recycelt werden" + }, + "8": { + "then": "Bio-Abfall kann hier recycelt werden" + }, + "9": { + "then": "Glasflaschen können hier recycelt werden" } }, "question": "Was kann hier recycelt werden?" @@ -8308,6 +8317,12 @@ }, "question": "Hat die Treppe einen Handlauf?" }, + "multilevels": { + "override": { + "question": "Zwischen welchen Stockwerken befindet sich diese Treppe?", + "render": "Diese Treppe ist zwischen den Stockwerken {level}" + } + }, "ramp": { "mappings": { "0": { @@ -8434,6 +8449,12 @@ "1": { "then": "Diese Straßenlaterne verwendet LEDs" }, + "10": { + "then": "Diese Straßenlaterne verwendet Hochdruck-Natriumdampflampen (orange mit weiß)" + }, + "11": { + "then": "Diese Straßenlaterne wird mit Gas beleuchtet" + }, "2": { "then": "Diese Straßenlaterne verwendet Glühlampenlicht" }, @@ -8457,12 +8478,6 @@ }, "9": { "then": "Diese Straßenlaterne verwendet Niederdruck-Natriumdampflampen (einfarbig orange)" - }, - "10": { - "then": "Diese Straßenlaterne verwendet Hochdruck-Natriumdampflampen (orange mit weiß)" - }, - "11": { - "then": "Diese Straßenlaterne wird mit Gas beleuchtet" } }, "question": "Mit welcher Art von Beleuchtung arbeitet diese Straßenlaterne?" @@ -8721,6 +8736,18 @@ }, "render": "Dieser Fahrkartenentwerter ist Teil einer Zugangsbarriere vom Typ {barrier}" }, + "payment-options": { + "override": { + "mappings+": { + "0": { + "then": "Dieser Fahrkartenentwerter akzeptiert die OV-Chipkaart" + }, + "1": { + "then": "Dieser Ticketentwerter akzeptiert die OV-Chipkaart" + } + } + } + }, "validator-operator": { "freeform": { "placeholder": "Name des Betreibers" @@ -8934,6 +8961,11 @@ }, "name": "Toiletten in anderen Einrichtungen", "tagRenderings": { + "opening_hours": { + "override": { + "question": "Wann ist der Ort, an dem sich diese Toiletten befinden, geöffnet?" + } + }, "toilet-access": { "mappings": { "0": { @@ -9406,6 +9438,13 @@ } } }, + "language_picker": { + "mappings": { + "0": { + "then": "Die Sprache wurde über einen URL-Parameter gesetzt und kann nicht vom Benutzer eingestellt werden.²" + } + } + }, "mangrove-keys": { "render": "Laden Sie den privaten Schlüssel für Ihr Mangrove-Konto herunter

Jeder, der diese Datei besitzt, kann mit Ihrer Identität Rezensionen vornehmen

" }, @@ -9527,6 +9566,27 @@ "1": { "question": "Verkauf von Getränken" }, + "10": { + "question": "Verkauf von Milch" + }, + "11": { + "question": "Verkauf von Brot" + }, + "12": { + "question": "Verkauf von Eiern" + }, + "13": { + "question": "Verkauf von Käse" + }, + "14": { + "question": "Verkauf von Honig" + }, + "15": { + "question": "Verkauf von Kartoffeln" + }, + "16": { + "question": "Verkauf von Blumen" + }, "2": { "question": "Verkauf von Süßigkeiten" }, @@ -9550,27 +9610,6 @@ }, "9": { "question": "Verkauf von Fahrradschläuchen" - }, - "10": { - "question": "Verkauf von Milch" - }, - "11": { - "question": "Verkauf von Brot" - }, - "12": { - "question": "Verkauf von Eiern" - }, - "13": { - "question": "Verkauf von Käse" - }, - "14": { - "question": "Verkauf von Honig" - }, - "15": { - "question": "Verkauf von Kartoffeln" - }, - "16": { - "question": "Verkauf von Blumen" } } } @@ -9611,6 +9650,24 @@ "1": { "then": "Süßigkeiten werden verkauft" }, + "10": { + "then": "Brot wird verkauft" + }, + "11": { + "then": "Eier werden verkauft" + }, + "12": { + "then": "Käse wird verkauft" + }, + "13": { + "then": "Honig wird verkauft" + }, + "14": { + "then": "Kartoffeln werden verkauft" + }, + "15": { + "then": "Blumen werden verkauft" + }, "2": { "then": "Lebensmittel werden verkauft" }, @@ -9634,24 +9691,6 @@ }, "9": { "then": "Milch wird verkauft" - }, - "10": { - "then": "Brot wird verkauft" - }, - "11": { - "then": "Eier werden verkauft" - }, - "12": { - "then": "Käse wird verkauft" - }, - "13": { - "then": "Honig wird verkauft" - }, - "14": { - "then": "Kartoffeln werden verkauft" - }, - "15": { - "then": "Blumen werden verkauft" } }, "question": "Was wird in diesem Automaten verkauft?", @@ -9988,4 +10027,4 @@ } } } -} \ No newline at end of file +} From ea4ccee5843f3800325df47e1217c7e59be67529 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Fri, 28 Jul 2023 13:32:07 +0200 Subject: [PATCH 4/9] Chore: translation sync --- assets/layers/questions/questions.json | 9 +- assets/layers/usersettings/usersettings.json | 3 +- .../mapcomplete-changes.json | 97 +++- langs/layers/de.json | 521 +++++++++--------- 4 files changed, 328 insertions(+), 302 deletions(-) diff --git a/assets/layers/questions/questions.json b/assets/layers/questions/questions.json index 1f56726803..3774c0a912 100644 --- a/assets/layers/questions/questions.json +++ b/assets/layers/questions/questions.json @@ -2154,20 +2154,23 @@ { "id": "survey_date", "question": { - "en": "When was this object last surveyed?" + "en": "When was this object last surveyed?", + "de": "Wann wurde dieses Objekt zuletzt geprüft?" }, "freeform": { "key": "survey:date", "type": "date" }, "render": { - "en": "This object was last surveyed on {survey:date}" + "en": "This object was last surveyed on {survey:date}", + "de": "Dieses Objekt wurde zuletzt geprüft am {survey:date}" }, "mappings": [ { "if": "survey:date:={_now:date}", "then": { - "en": "This object was last surveyed today" + "en": "This object was last surveyed today", + "de": "Dieses Objekt wurde heute zuletzt geprüft" } } ] diff --git a/assets/layers/usersettings/usersettings.json b/assets/layers/usersettings/usersettings.json index 2f4fa5671f..183ff57423 100644 --- a/assets/layers/usersettings/usersettings.json +++ b/assets/layers/usersettings/usersettings.json @@ -39,7 +39,8 @@ "if": "__url_parameter_initialized:language=yes", "icon": "./assets/layers/usersettings/translate_disabled.svg", "then": { - "en": "The language was set via an URL-parameter and cannot be set by the user.²" + "en": "The language was set via an URL-parameter and cannot be set by the user.²", + "de": "Die Sprache wurde über einen URL-Parameter gesetzt und kann nicht vom Benutzer eingestellt werden.²" } } ] diff --git a/assets/themes/mapcomplete-changes/mapcomplete-changes.json b/assets/themes/mapcomplete-changes/mapcomplete-changes.json index 56555e8719..deda66b656 100644 --- a/assets/themes/mapcomplete-changes/mapcomplete-changes.json +++ b/assets/themes/mapcomplete-changes/mapcomplete-changes.json @@ -1,13 +1,19 @@ { "id": "mapcomplete-changes", "title": { - "en": "Changes made with MapComplete" + "en": "Changes made with MapComplete", + "de": "Mit MapComplete erstellte Änderungen", + "nl": "Wijzigingen gemaakt met MapComplete" }, "shortDescription": { - "en": "Shows changes made by MapComplete" + "en": "Show changes made with MapComplete", + "de": "Mit MapComplete erstellte Änderungen anzeigen", + "nl": "Toon wijzigingen gemaakt met MapComplete" }, "description": { - "en": "This maps shows all the changes made with MapComplete" + "en": "This maps shows all the changes made with MapComplete", + "de": "Diese Karte zeigt alle mit MapComplete vorgenommenen Änderungen", + "nl": "Deze kaart toont alle wijzigingen die met MapComplete gemaakt werden" }, "icon": "./assets/svg/logo.svg", "hideFromOverview": true, @@ -20,7 +26,9 @@ { "id": "mapcomplete-changes", "name": { - "en": "Changeset centers" + "en": "Changeset centers", + "de": "Zentrum der Änderungssätze", + "nl": "Centerpunt van changeset" }, "minzoom": 0, "source": { @@ -31,41 +39,51 @@ }, "title": { "render": { - "en": "Changeset for {theme}" + "en": "Changeset for {theme}", + "de": "Änderungssatz für {theme}" } }, "description": { - "en": "Shows all MapComplete changes" + "en": "Show all MapComplete changes", + "de": "Alle MapComplete-Änderungen anzeigen", + "nl": "Toon alle MapComplete wijzigingen" }, "tagRenderings": [ { "id": "show_changeset_id", "render": { - "en": "Changeset {id}" + "en": "Changeset {id}", + "de": "Änderungssatz {id}" } }, { "id": "contributor", "question": { - "en": "What contributor did make this change?" + "en": "Which contributor made this change?", + "de": "Welcher Mitwirkende hat diese Änderung vorgenommen?", + "nl": "Welke bijdrager maakte deze wijziging?" }, "freeform": { "key": "user" }, "render": { - "en": "Change made by {user}" + "en": "Change made by {user}", + "de": "Änderung gemacht von {user}", + "nl": "Wijziging gemaakt door {user}" } }, { "id": "theme-id", "question": { - "en": "What theme was used to make this change?" + "en": "What theme was used to make this change?", + "de": "Welches Thema wurde für diese Änderung verwendet?" }, "freeform": { "key": "theme" }, "render": { - "en": "Change with theme {theme}" + "en": "Change with theme {theme}", + "de": "Geändert mit Thema {theme}" } }, { @@ -74,19 +92,27 @@ "key": "locale" }, "question": { - "en": "What locale (language) was this change made in?" + "en": "What locale (language) was this change made in?", + "de": "In welcher Sprache wurde diese Änderung vorgenommen?", + "nl": "In welke locale (taal) werd deze wijziging gemaakt?" }, "render": { - "en": "User locale is {locale}" + "en": "User locale is {locale}", + "de": "Usersprache ist {locale}", + "nl": "De gebruikerstaal is {locale}" } }, { "id": "host", "render": { - "en": "Change with with {host}" + "en": "Change made with {host}", + "de": "Änderung vorgenommen mit {host}", + "nl": "Wijziging gemaakt met {host}" }, "question": { - "en": "What host (website) was this change made with?" + "en": "What host (website) was this change made with?", + "de": "Mit welchem Host / welcher Website wurde diese Änderung gemacht?", + "nl": "Met welke host (website) werd deze wijziging gemaakt?" }, "freeform": { "key": "host" @@ -107,10 +133,12 @@ { "id": "version", "question": { - "en": "What version of MapComplete was used to make this change?" + "en": "What version of MapComplete was used to make this change?", + "de": "Mit welcher Version von MapComplete wurde diese Änderung gemacht?" }, "render": { - "en": "Made with {editor}" + "en": "Made with {editor}", + "de": "Erstellt mit {editor}" }, "freeform": { "key": "editor" @@ -452,7 +480,9 @@ } ], "question": { - "en": "Themename contains {search}" + "en": "Theme name contains {search}", + "de": "Themenname enthält {search}", + "nl": "Themenaam bevat {search}" } } ] @@ -468,7 +498,9 @@ } ], "question": { - "en": "Made by contributor {search}" + "en": "Made by contributor {search}", + "de": "Erstellt von {search}", + "nl": "Gemaakt door bijdrager {search}" } } ] @@ -484,7 +516,9 @@ } ], "question": { - "en": "Not made by contributor {search}" + "en": "Not made by contributor {search}", + "de": "Nicht erstellt von {search}", + "nl": "Niet gemaakt door bijdrager {search}" } } ] @@ -501,7 +535,9 @@ } ], "question": { - "en": "Made before {search}" + "en": "Made before {search}", + "de": "Erstellt vor {search}", + "nl": "Gemaakt voor {search}" } } ] @@ -518,7 +554,9 @@ } ], "question": { - "en": "Made after {search}" + "en": "Made after {search}", + "de": "Erstellt nach {search}", + "nl": "Gemaakt na {search}" } } ] @@ -534,7 +572,9 @@ } ], "question": { - "en": "User language (iso-code) {search}" + "en": "User language (iso-code) {search}", + "de": "Benutzersprache (ISO-Code) {search}", + "nl": "De taal van de bijdrager is {search}" } } ] @@ -550,7 +590,9 @@ } ], "question": { - "en": "Made with host {search}" + "en": "Made with host {search}", + "de": "Erstellt mit Host {search}", + "nl": "Gemaakt met host {search}" } } ] @@ -561,7 +603,9 @@ { "osmTags": "add-image>0", "question": { - "en": "Changeset added at least one image" + "en": "Changeset added at least one image", + "de": "Changeset fügte mindestens ein Bild hinzu", + "nl": "Changeset bevat minstens één afbeelding" } } ] @@ -576,7 +620,8 @@ { "id": "link_to_more", "render": { - "en": "More statistics can be found here" + "en": "More statistics can be found here", + "de": "Mehr Statistiken gibt es hier" } }, { diff --git a/langs/layers/de.json b/langs/layers/de.json index c8b2bf68c0..362d52f670 100644 --- a/langs/layers/de.json +++ b/langs/layers/de.json @@ -35,16 +35,6 @@ "1": { "title": "eine freistehende Posterbox" }, - "10": { - "description": "Verwendet für Werbeschilder, Leuchtreklamen, Logos und institutionelle Eingangsschilder", - "title": "ein Schild" - }, - "11": { - "title": "eine Skulptur" - }, - "12": { - "title": "eine Wandmalerei" - }, "2": { "title": "eine wandmontierte Posterbox" }, @@ -71,6 +61,16 @@ }, "9": { "title": "ein Totem" + }, + "10": { + "description": "Verwendet für Werbeschilder, Leuchtreklamen, Logos und institutionelle Eingangsschilder", + "title": "ein Schild" + }, + "11": { + "title": "eine Skulptur" + }, + "12": { + "title": "eine Wandmalerei" } }, "tagRenderings": { @@ -165,9 +165,6 @@ "1": { "then": "Dies ist ein Brett" }, - "10": { - "then": "Dies ist eine Wandmalerei" - }, "2": { "then": "Dies ist eine Litfaßsäule" }, @@ -191,6 +188,9 @@ }, "9": { "then": "Dies ist ein Totem" + }, + "10": { + "then": "Dies ist eine Wandmalerei" } }, "question": "Welche Art von Werbung ist das?", @@ -205,9 +205,6 @@ "1": { "then": "Brett" }, - "10": { - "then": "Wandmalerei" - }, "2": { "then": "Posterbox" }, @@ -231,6 +228,9 @@ }, "9": { "then": "Totem" + }, + "10": { + "then": "Wandmalerei" } } } @@ -312,15 +312,6 @@ "1": { "then": "Wandbild" }, - "10": { - "then": "Azulejo (spanische dekorative Fliesenarbeit)" - }, - "11": { - "then": "Fliesenarbeit" - }, - "12": { - "then": "Holzschnitzerei" - }, "2": { "then": "Malerei" }, @@ -344,6 +335,15 @@ }, "9": { "then": "Relief" + }, + "10": { + "then": "Azulejo (spanische dekorative Fliesenarbeit)" + }, + "11": { + "then": "Fliesenarbeit" + }, + "12": { + "then": "Holzschnitzerei" } }, "question": "Um welche Art Kunstwerk handelt es sich?", @@ -1830,27 +1830,6 @@ "1": { "question": "Verfügt über einen
Schuko-Stecker ohne Erdungsstift (CEE7/4 Typ F)
" }, - "10": { - "question": "Hat einen
Typ 2 (Mennekes)
Anschluss mit Kabel" - }, - "11": { - "question": "Hat einen
Tesla Supercharger CCS (Typ 2 CSS vonTesla)
Anschluss" - }, - "12": { - "question": "Hat einen
Tesla Supercharger (Destination)
Anschluss" - }, - "13": { - "question": "Hat einen
Tesla Supercharger (Destination) (Typ 2 von Tesla)
Anschluss mit Kabel" - }, - "14": { - "question": "Hat einen
USB-Anschluss zum Aufladen von Telefonen und kleinen Elektrogeräten
" - }, - "15": { - "question": "Hat einen
Bosch Active Connect Anschluss mit 3 Pins
und Kabel" - }, - "16": { - "question": "Hat einen
Bosch Active Connect Anschluss mit 5 Pins
und Kabel" - }, "2": { "question": "Verfügt über einen
europäischen Netzstecker mit Erdungsstift (CEE7/4 Typ E)
Anschluss" }, @@ -1874,6 +1853,27 @@ }, "9": { "question": "Hat einen
Typ 2 CCS (Mennekes)
Anschluss" + }, + "10": { + "question": "Hat einen
Typ 2 (Mennekes)
Anschluss mit Kabel" + }, + "11": { + "question": "Hat einen
Tesla Supercharger CCS (Typ 2 CSS vonTesla)
Anschluss" + }, + "12": { + "question": "Hat einen
Tesla Supercharger (Destination)
Anschluss" + }, + "13": { + "question": "Hat einen
Tesla Supercharger (Destination) (Typ 2 von Tesla)
Anschluss mit Kabel" + }, + "14": { + "question": "Hat einen
USB-Anschluss zum Aufladen von Telefonen und kleinen Elektrogeräten
" + }, + "15": { + "question": "Hat einen
Bosch Active Connect Anschluss mit 3 Pins
und Kabel" + }, + "16": { + "question": "Hat einen
Bosch Active Connect Anschluss mit 5 Pins
und Kabel" } } } @@ -1929,6 +1929,30 @@ "1": { "then": "Schuko-Stecker ohne Erdungsstift (CEE7/4 Typ F)" }, + "2": { + "then": "Europäischer Netzstecker mit Erdungsstift (CEE7/4 Typ E)" + }, + "3": { + "then": "Europäischer Netzstecker mit Erdungsstift (CEE7/4 Typ E)" + }, + "4": { + "then": "Chademo-Anschluss" + }, + "5": { + "then": "Chademo-Anschluss" + }, + "6": { + "then": "Typ 1 mit Kabel (J1772)" + }, + "7": { + "then": "Typ 1 mit Kabel (J1772)" + }, + "8": { + "then": "Typ 1 ohne Kabel (J1772)" + }, + "9": { + "then": " Typ 1 ohne Kabel (J1772)" + }, "10": { "then": "Typ 1 CCS (Typ 1 Combo)" }, @@ -1959,9 +1983,6 @@ "19": { "then": "Typ 2 mit Kabel (mennekes)" }, - "2": { - "then": "Europäischer Netzstecker mit Erdungsstift (CEE7/4 Typ E)" - }, "20": { "then": "Tesla Supercharger CCS (Typ 2 CSS von Tesla)" }, @@ -1992,32 +2013,11 @@ "29": { "then": " Bosch Active Connect mit 3 Pins und Kabel" }, - "3": { - "then": "Europäischer Netzstecker mit Erdungsstift (CEE7/4 Typ E)" - }, "30": { "then": "Bosch Active Connect mit 5 Pins und Kabel" }, "31": { "then": " Bosch Active Connect mit 5 Pins und Kabel" - }, - "4": { - "then": "Chademo-Anschluss" - }, - "5": { - "then": "Chademo-Anschluss" - }, - "6": { - "then": "Typ 1 mit Kabel (J1772)" - }, - "7": { - "then": "Typ 1 mit Kabel (J1772)" - }, - "8": { - "then": "Typ 1 ohne Kabel (J1772)" - }, - "9": { - "then": " Typ 1 ohne Kabel (J1772)" } }, "question": "Welche Ladeanschlüsse gibt es hier?" @@ -3555,15 +3555,6 @@ "1": { "then": "Dieser Radweg hat einen festen Belag" }, - "10": { - "then": "Dieser Radweg besteht aus feinem Schotter" - }, - "11": { - "then": "Der Radweg ist aus Kies" - }, - "12": { - "then": "Dieser Radweg besteht aus Rohboden" - }, "2": { "then": "Der Radweg ist aus Asphalt" }, @@ -3587,6 +3578,15 @@ }, "9": { "then": "Der Radweg ist aus Schotter" + }, + "10": { + "then": "Dieser Radweg besteht aus feinem Schotter" + }, + "11": { + "then": "Der Radweg ist aus Kies" + }, + "12": { + "then": "Dieser Radweg besteht aus Rohboden" } }, "question": "Was ist der Belag dieses Radwegs?", @@ -3635,15 +3635,6 @@ "1": { "then": "Dieser Radweg hat einen festen Belag" }, - "10": { - "then": "Dieser Radweg besteht aus feinem Schotter" - }, - "11": { - "then": "Der Radweg ist aus Kies" - }, - "12": { - "then": "Dieser Radweg besteht aus Rohboden" - }, "2": { "then": "Der Radweg ist aus Asphalt" }, @@ -3667,6 +3658,15 @@ }, "9": { "then": "Der Radweg ist aus Schotter" + }, + "10": { + "then": "Dieser Radweg besteht aus feinem Schotter" + }, + "11": { + "then": "Der Radweg ist aus Kies" + }, + "12": { + "then": "Dieser Radweg besteht aus Rohboden" } }, "question": "Was ist der Belag dieser Straße?", @@ -4606,6 +4606,30 @@ "1": { "then": "Die Fitness-Station hat ein Schild mit Anweisungen für eine bestimmte Übung." }, + "2": { + "then": "Die Fitness-Station hat eine Einrichtung für Sit-ups." + }, + "3": { + "then": "Die Fitness-Station hat eine Vorrichtung für Liegestütze. In der Regel eine oder mehrere niedrige Reckstangen." + }, + "4": { + "then": "Die Fitness-Station hat Stangen zum Dehnen." + }, + "5": { + "then": "Die Fitness-Station hat eine Vorrichtung für Rückenstrecker (Hyperextensions)." + }, + "6": { + "then": "Die Fitness-Station hat Ringe für Gymnastikübungen." + }, + "7": { + "then": "Die Fitness-Station hat eine horizontale Leiter (Monkey Bars)." + }, + "8": { + "then": "Die Fitness-Station hat eine Sprossenwand zum Klettern." + }, + "9": { + "then": "Die Fitness-Station hat Pfosten für Slalomübungen." + }, "10": { "then": "Die Fitness-Station hat Trittsteine." }, @@ -4636,9 +4660,6 @@ "19": { "then": "Die Fitness-Station hat Kampfseile (battle ropes)." }, - "2": { - "then": "Die Fitness-Station hat eine Einrichtung für Sit-ups." - }, "20": { "then": "Die Fitness-Station hat ein Fahrradergometer." }, @@ -4653,27 +4674,6 @@ }, "24": { "then": "Die Fitness-Station hat eine Slackline." - }, - "3": { - "then": "Die Fitness-Station hat eine Vorrichtung für Liegestütze. In der Regel eine oder mehrere niedrige Reckstangen." - }, - "4": { - "then": "Die Fitness-Station hat Stangen zum Dehnen." - }, - "5": { - "then": "Die Fitness-Station hat eine Vorrichtung für Rückenstrecker (Hyperextensions)." - }, - "6": { - "then": "Die Fitness-Station hat Ringe für Gymnastikübungen." - }, - "7": { - "then": "Die Fitness-Station hat eine horizontale Leiter (Monkey Bars)." - }, - "8": { - "then": "Die Fitness-Station hat eine Sprossenwand zum Klettern." - }, - "9": { - "then": "Die Fitness-Station hat Pfosten für Slalomübungen." } }, "question": "Welche Übungsgeräte gibt es an dieser Fitness-Station?" @@ -4780,21 +4780,6 @@ "1": { "then": "Dies ist eine Pommesbude" }, - "10": { - "then": "Hier werden chinesische Gerichte serviert" - }, - "11": { - "then": "Hier werden griechische Gerichte serviert" - }, - "12": { - "then": "Hier werden indische Gerichte serviert" - }, - "13": { - "then": "Hier werden türkische Gerichte serviert" - }, - "14": { - "then": "Hier werden thailändische Gerichte serviert" - }, "2": { "then": "Bietet vorwiegend Pastagerichte an" }, @@ -4818,6 +4803,21 @@ }, "9": { "then": "Hier werden französische Gerichte serviert" + }, + "10": { + "then": "Hier werden chinesische Gerichte serviert" + }, + "11": { + "then": "Hier werden griechische Gerichte serviert" + }, + "12": { + "then": "Hier werden indische Gerichte serviert" + }, + "13": { + "then": "Hier werden türkische Gerichte serviert" + }, + "14": { + "then": "Hier werden thailändische Gerichte serviert" } }, "question": "Was für Essen gibt es hier?", @@ -6036,19 +6036,6 @@ } } }, - "10": { - "options": { - "0": { - "question": "Alle Notizen" - }, - "1": { - "question": "Importnotizen ausblenden" - }, - "2": { - "question": "Nur Importnotizen anzeigen" - } - } - }, "2": { "options": { "0": { @@ -6104,6 +6091,19 @@ "question": "Nur offene Notizen anzeigen" } } + }, + "10": { + "options": { + "0": { + "question": "Alle Notizen" + }, + "1": { + "question": "Importnotizen ausblenden" + }, + "2": { + "question": "Nur Importnotizen anzeigen" + } + } } }, "name": "OpenStreetMap-Hinweise", @@ -6432,21 +6432,6 @@ "1": { "then": "Dies ist ein normaler Stellplatz." }, - "10": { - "then": "Dies ist ein Stellplatz, der für Eltern mit Kindern reserviert ist." - }, - "11": { - "then": "Dies ist ein Stellplatz, der für das Personal reserviert ist." - }, - "12": { - "then": "Dies ist ein Stellplatz, der für Taxis reserviert ist." - }, - "13": { - "then": "Dies ist ein Stellplatz, der für Fahrzeuge mit Anhänger reserviert ist." - }, - "14": { - "then": "Dies ist ein Stellplatz, der für Carsharing reserviert ist." - }, "2": { "then": "Dies ist ein Behindertenstellplatz." }, @@ -6470,6 +6455,21 @@ }, "9": { "then": "Dies ist ein Stellplatz, der für Motorräder reserviert ist." + }, + "10": { + "then": "Dies ist ein Stellplatz, der für Eltern mit Kindern reserviert ist." + }, + "11": { + "then": "Dies ist ein Stellplatz, der für das Personal reserviert ist." + }, + "12": { + "then": "Dies ist ein Stellplatz, der für Taxis reserviert ist." + }, + "13": { + "then": "Dies ist ein Stellplatz, der für Fahrzeuge mit Anhänger reserviert ist." + }, + "14": { + "then": "Dies ist ein Stellplatz, der für Carsharing reserviert ist." } }, "question": "Welche Art von Stellplatz ist dies?" @@ -7452,6 +7452,30 @@ "1": { "question": "Recycling von Batterien" }, + "2": { + "question": "Recycling von Getränkekartons" + }, + "3": { + "question": "Recycling von Dosen" + }, + "4": { + "question": "Recycling von Kleidung" + }, + "5": { + "question": "Recycling von Speiseöl" + }, + "6": { + "question": "Recycling von Motoröl" + }, + "7": { + "question": "Recycling von Leuchtstoffröhren" + }, + "8": { + "question": "Recycling von Grünabfällen" + }, + "9": { + "question": "Recycling von Glasflaschen" + }, "10": { "question": "Recycling von Glas" }, @@ -7482,35 +7506,11 @@ "19": { "question": "Recycling von Restabfällen" }, - "2": { - "question": "Recycling von Getränkekartons" - }, "20": { "question": "Recycling von Druckerpatronen" }, "21": { "question": "Recycling von Fahrrädern" - }, - "3": { - "question": "Recycling von Dosen" - }, - "4": { - "question": "Recycling von Kleidung" - }, - "5": { - "question": "Recycling von Speiseöl" - }, - "6": { - "question": "Recycling von Motoröl" - }, - "7": { - "question": "Recycling von Leuchtstoffröhren" - }, - "8": { - "question": "Recycling von Grünabfällen" - }, - "9": { - "question": "Recycling von Glasflaschen" } } }, @@ -7578,6 +7578,30 @@ "1": { "then": "Getränkekartons können hier recycelt werden" }, + "2": { + "then": "Dosen können hier recycelt werden" + }, + "3": { + "then": "Kleidung kann hier recycelt werden" + }, + "4": { + "then": "Speiseöl kann hier recycelt werden" + }, + "5": { + "then": "Motoröl kann hier recycelt werden" + }, + "6": { + "then": "Hier können Leuchtstoffröhren recycelt werden" + }, + "7": { + "then": "Grünabfälle können hier recycelt werden" + }, + "8": { + "then": "Bio-Abfall kann hier recycelt werden" + }, + "9": { + "then": "Glasflaschen können hier recycelt werden" + }, "10": { "then": "Glas kann hier recycelt werden" }, @@ -7608,9 +7632,6 @@ "19": { "then": "Schuhe können hier recycelt werden" }, - "2": { - "then": "Dosen können hier recycelt werden" - }, "20": { "then": "Elektrokleingeräte können hier recycelt werden" }, @@ -7625,27 +7646,6 @@ }, "24": { "then": "Fahrräder können hier recycelt werden" - }, - "3": { - "then": "Kleidung kann hier recycelt werden" - }, - "4": { - "then": "Speiseöl kann hier recycelt werden" - }, - "5": { - "then": "Motoröl kann hier recycelt werden" - }, - "6": { - "then": "Hier können Leuchtstoffröhren recycelt werden" - }, - "7": { - "then": "Grünabfälle können hier recycelt werden" - }, - "8": { - "then": "Bio-Abfall kann hier recycelt werden" - }, - "9": { - "then": "Glasflaschen können hier recycelt werden" } }, "question": "Was kann hier recycelt werden?" @@ -8317,12 +8317,6 @@ }, "question": "Hat die Treppe einen Handlauf?" }, - "multilevels": { - "override": { - "question": "Zwischen welchen Stockwerken befindet sich diese Treppe?", - "render": "Diese Treppe ist zwischen den Stockwerken {level}" - } - }, "ramp": { "mappings": { "0": { @@ -8449,12 +8443,6 @@ "1": { "then": "Diese Straßenlaterne verwendet LEDs" }, - "10": { - "then": "Diese Straßenlaterne verwendet Hochdruck-Natriumdampflampen (orange mit weiß)" - }, - "11": { - "then": "Diese Straßenlaterne wird mit Gas beleuchtet" - }, "2": { "then": "Diese Straßenlaterne verwendet Glühlampenlicht" }, @@ -8478,6 +8466,12 @@ }, "9": { "then": "Diese Straßenlaterne verwendet Niederdruck-Natriumdampflampen (einfarbig orange)" + }, + "10": { + "then": "Diese Straßenlaterne verwendet Hochdruck-Natriumdampflampen (orange mit weiß)" + }, + "11": { + "then": "Diese Straßenlaterne wird mit Gas beleuchtet" } }, "question": "Mit welcher Art von Beleuchtung arbeitet diese Straßenlaterne?" @@ -8736,18 +8730,6 @@ }, "render": "Dieser Fahrkartenentwerter ist Teil einer Zugangsbarriere vom Typ {barrier}" }, - "payment-options": { - "override": { - "mappings+": { - "0": { - "then": "Dieser Fahrkartenentwerter akzeptiert die OV-Chipkaart" - }, - "1": { - "then": "Dieser Ticketentwerter akzeptiert die OV-Chipkaart" - } - } - } - }, "validator-operator": { "freeform": { "placeholder": "Name des Betreibers" @@ -8961,11 +8943,6 @@ }, "name": "Toiletten in anderen Einrichtungen", "tagRenderings": { - "opening_hours": { - "override": { - "question": "Wann ist der Ort, an dem sich diese Toiletten befinden, geöffnet?" - } - }, "toilet-access": { "mappings": { "0": { @@ -9566,27 +9543,6 @@ "1": { "question": "Verkauf von Getränken" }, - "10": { - "question": "Verkauf von Milch" - }, - "11": { - "question": "Verkauf von Brot" - }, - "12": { - "question": "Verkauf von Eiern" - }, - "13": { - "question": "Verkauf von Käse" - }, - "14": { - "question": "Verkauf von Honig" - }, - "15": { - "question": "Verkauf von Kartoffeln" - }, - "16": { - "question": "Verkauf von Blumen" - }, "2": { "question": "Verkauf von Süßigkeiten" }, @@ -9610,6 +9566,27 @@ }, "9": { "question": "Verkauf von Fahrradschläuchen" + }, + "10": { + "question": "Verkauf von Milch" + }, + "11": { + "question": "Verkauf von Brot" + }, + "12": { + "question": "Verkauf von Eiern" + }, + "13": { + "question": "Verkauf von Käse" + }, + "14": { + "question": "Verkauf von Honig" + }, + "15": { + "question": "Verkauf von Kartoffeln" + }, + "16": { + "question": "Verkauf von Blumen" } } } @@ -9650,24 +9627,6 @@ "1": { "then": "Süßigkeiten werden verkauft" }, - "10": { - "then": "Brot wird verkauft" - }, - "11": { - "then": "Eier werden verkauft" - }, - "12": { - "then": "Käse wird verkauft" - }, - "13": { - "then": "Honig wird verkauft" - }, - "14": { - "then": "Kartoffeln werden verkauft" - }, - "15": { - "then": "Blumen werden verkauft" - }, "2": { "then": "Lebensmittel werden verkauft" }, @@ -9691,6 +9650,24 @@ }, "9": { "then": "Milch wird verkauft" + }, + "10": { + "then": "Brot wird verkauft" + }, + "11": { + "then": "Eier werden verkauft" + }, + "12": { + "then": "Käse wird verkauft" + }, + "13": { + "then": "Honig wird verkauft" + }, + "14": { + "then": "Kartoffeln werden verkauft" + }, + "15": { + "then": "Blumen werden verkauft" } }, "question": "Was wird in diesem Automaten verkauft?", @@ -10027,4 +10004,4 @@ } } } -} +} \ No newline at end of file From 393d4e75d8be0373a09778b0691672ead3eb9d8e Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Fri, 28 Jul 2023 13:34:10 +0200 Subject: [PATCH 5/9] Chore: translation sync --- langs/layers/de.json | 6 +++--- langs/layers/en.json | 6 +++--- langs/layers/nl.json | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/langs/layers/de.json b/langs/layers/de.json index 362d52f670..3f2b2918f2 100644 --- a/langs/layers/de.json +++ b/langs/layers/de.json @@ -5163,13 +5163,13 @@ "hs-club-mate": { "mappings": { "0": { - "then": "In diesem Hackerspace gibt es Club Mate" + "then": "In diesem Hackerspace gibt es Club-Mate" }, "1": { - "then": "In diesem Hackerspace gibt es kein Club Mate" + "then": "In diesem Hackerspace gibt es kein Club-Mate" } }, - "question": "Gibt es in diesem Hackerspace Club Mate?" + "question": "Gibt es in diesem Hackerspace Club-Mate?" }, "is_makerspace": { "mappings": { diff --git a/langs/layers/en.json b/langs/layers/en.json index 4959af6b1c..bbbdb9367d 100644 --- a/langs/layers/en.json +++ b/langs/layers/en.json @@ -5163,13 +5163,13 @@ "hs-club-mate": { "mappings": { "0": { - "then": "This hackerspace serves club mate" + "then": "This hackerspace serves Club-Mate" }, "1": { - "then": "This hackerspace does not serve club mate" + "then": "This hackerspace does not serve Club-Mate" } }, - "question": "Does this hackerspace serve Club Mate?" + "question": "Does this hackerspace serve Club-Mate?" }, "is_makerspace": { "mappings": { diff --git a/langs/layers/nl.json b/langs/layers/nl.json index ff66c6600e..477ddd2c39 100644 --- a/langs/layers/nl.json +++ b/langs/layers/nl.json @@ -4939,13 +4939,13 @@ "hs-club-mate": { "mappings": { "0": { - "then": "Deze hackerspace biedt clube-mate aan" + "then": "Deze hackerspace biedt Club-Mate aan" }, "1": { - "then": "Deze hackerspace biedt geen club-mate aan" + "then": "Deze hackerspace biedt geen Club-Mate aan" } }, - "question": "Biedt deze hackerspace club-mate aan?" + "question": "Biedt deze hackerspace Club-Mate aan?" }, "is_makerspace": { "mappings": { From 56ea1163bb7c272cec717076da452ba069e82b3c Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Fri, 28 Jul 2023 14:11:00 +0200 Subject: [PATCH 6/9] Themes: add extra check so that in a mapping cannot override the , fix two such instances --- assets/layers/climbing_gym/climbing_gym.json | 1 - assets/themes/campersite/campersite.json | 9 +- .../ThemeConfig/Conversion/Validation.ts | 227 +++++++++++------- 3 files changed, 145 insertions(+), 92 deletions(-) diff --git a/assets/layers/climbing_gym/climbing_gym.json b/assets/layers/climbing_gym/climbing_gym.json index 7948a2b9e1..ae085eda41 100644 --- a/assets/layers/climbing_gym/climbing_gym.json +++ b/assets/layers/climbing_gym/climbing_gym.json @@ -135,7 +135,6 @@ "de": "Kletterschuhe können hier ausgeliehen werden" }, "addExtraTags": [ - "service:climbing_shoes:rental:fee=", "service:climbing_shoes:rental:charge=" ] }, diff --git a/assets/themes/campersite/campersite.json b/assets/themes/campersite/campersite.json index 64dc9a0206..40eecd5715 100644 --- a/assets/themes/campersite/campersite.json +++ b/assets/themes/campersite/campersite.json @@ -231,12 +231,7 @@ } }, { - "if": { - "and": [ - "fee=no", - "charge=" - ] - }, + "if": "fee=no", "then": { "en": "Can be used for free", "id": "Boleh digunakan tanpa bayaran", @@ -1562,4 +1557,4 @@ ] }, "credits": "joost schouppe" -} \ No newline at end of file +} diff --git a/src/Models/ThemeConfig/Conversion/Validation.ts b/src/Models/ThemeConfig/Conversion/Validation.ts index 6588e5edfd..89fe06697a 100644 --- a/src/Models/ThemeConfig/Conversion/Validation.ts +++ b/src/Models/ThemeConfig/Conversion/Validation.ts @@ -1,21 +1,22 @@ -import { DesugaringStep, Each, Fuse, On } from "./Conversion" -import { LayerConfigJson } from "../Json/LayerConfigJson" +import {DesugaringStep, Each, Fuse, On} from "./Conversion" +import {LayerConfigJson} from "../Json/LayerConfigJson" import LayerConfig from "../LayerConfig" -import { Utils } from "../../../Utils" +import {Utils} from "../../../Utils" import Constants from "../../Constants" -import { Translation } from "../../../UI/i18n/Translation" -import { LayoutConfigJson } from "../Json/LayoutConfigJson" +import {Translation} from "../../../UI/i18n/Translation" +import {LayoutConfigJson} from "../Json/LayoutConfigJson" import LayoutConfig from "../LayoutConfig" -import { TagRenderingConfigJson } from "../Json/TagRenderingConfigJson" -import { TagUtils } from "../../../Logic/Tags/TagUtils" -import { ExtractImages } from "./FixImages" -import { And } from "../../../Logic/Tags/And" +import {TagRenderingConfigJson} from "../Json/TagRenderingConfigJson" +import {TagUtils} from "../../../Logic/Tags/TagUtils" +import {ExtractImages} from "./FixImages" +import {And} from "../../../Logic/Tags/And" import Translations from "../../../UI/i18n/Translations" import Svg from "../../../Svg" import FilterConfigJson from "../Json/FilterConfigJson" import DeleteConfig from "../DeleteConfig" -import { QuestionableTagRenderingConfigJson } from "../Json/QuestionableTagRenderingConfigJson" +import {QuestionableTagRenderingConfigJson} from "../Json/QuestionableTagRenderingConfigJson" import Validators from "../../../UI/InputElement/Validators" +import TagRenderingConfig from "../TagRenderingConfig"; class ValidateLanguageCompleteness extends DesugaringStep { private readonly _languages: string[] @@ -46,12 +47,12 @@ class ValidateLanguageCompleteness extends DesugaringStep { .forEach((missing) => { errors.push( context + - "A theme should be translation-complete for " + - neededLanguage + - ", but it lacks a translation for " + - missing.context + - ".\n\tThe known translation is " + - missing.tr.textFor("en") + "A theme should be translation-complete for " + + neededLanguage + + ", but it lacks a translation for " + + missing.context + + ".\n\tThe known translation is " + + missing.tr.textFor("en") ) }) } @@ -85,7 +86,7 @@ export class DoesImageExist extends DesugaringStep { context: string ): { result: string; errors?: string[]; warnings?: string[]; information?: string[] } { if (this._ignore?.has(image)) { - return { result: image } + return {result: image} } const errors = [] @@ -93,22 +94,22 @@ export class DoesImageExist extends DesugaringStep { const information = [] if (image.indexOf("{") >= 0) { information.push("Ignoring image with { in the path: " + image) - return { result: image } + return {result: image} } if (image === "assets/SocialImage.png") { - return { result: image } + return {result: image} } if (image.match(/[a-z]*/)) { if (Svg.All[image + ".svg"] !== undefined) { // This is a builtin img, e.g. 'checkmark' or 'crosshair' - return { result: image } + return {result: image} } } if (image.startsWith("<") && image.endsWith(">")) { // This is probably HTML, you're on your own here - return { result: image } + return {result: image} } if (!this._knownImagePaths.has(image)) { @@ -177,15 +178,15 @@ class ValidateTheme extends DesugaringStep { if (json["units"] !== undefined) { errors.push( "The theme " + - json.id + - " has units defined - these should be defined on the layer instead. (Hint: use overrideAll: { '+units': ... }) " + json.id + + " has units defined - these should be defined on the layer instead. (Hint: use overrideAll: { '+units': ... }) " ) } if (json["roamingRenderings"] !== undefined) { errors.push( "Theme " + - json.id + - " contains an old 'roamingRenderings'. Use an 'overrideAll' instead" + json.id + + " contains an old 'roamingRenderings'. Use an 'overrideAll' instead" ) } } @@ -197,10 +198,10 @@ class ValidateTheme extends DesugaringStep { for (const remoteImage of remoteImages) { errors.push( "Found a remote image: " + - remoteImage + - " in theme " + - json.id + - ", please download it." + remoteImage + + " in theme " + + json.id + + ", please download it." ) } for (const image of images) { @@ -227,12 +228,12 @@ class ValidateTheme extends DesugaringStep { if (theme.id !== filename) { errors.push( "Theme ids should be the same as the name.json, but we got id: " + - theme.id + - " and filename " + - filename + - " (" + - this._path + - ")" + theme.id + + " and filename " + + filename + + " (" + + this._path + + ")" ) } this._validateImage.convertJoin( @@ -312,7 +313,7 @@ class OverrideShadowingCheck extends DesugaringStep { ): { result: LayoutConfigJson; errors?: string[]; warnings?: string[] } { const overrideAll = json.overrideAll if (overrideAll === undefined) { - return { result: json } + return {result: json} } const errors = [] @@ -339,7 +340,7 @@ class OverrideShadowingCheck extends DesugaringStep { } } - return { result: json, errors } + return {result: json, errors} } } @@ -383,6 +384,51 @@ export class PrevalidateTheme extends Fuse { } } +export class DetectConflictingAddExtraTags extends DesugaringStep { + constructor() { + super("The `if`-part in a mapping might set some keys. Those key are not allowed to be set in the `addExtraTags`, as this might result in conflicting values", [], "DetectConflictingAddExtraTags"); + } + + convert(json: TagRenderingConfigJson, context: string): { + result: TagRenderingConfigJson; + errors?: string[]; + warnings?: string[]; + information?: string[] + } { + + if (!(json.mappings?.length > 0)) { + return {result: json} + } + + const tagRendering = new TagRenderingConfig(json) + + const errors = [] + for (let i = 0; i < tagRendering.mappings.length; i++) { + const mapping = tagRendering.mappings[i]; + if (!mapping.addExtraTags) { + continue + } + const keysInMapping = new Set(mapping.if.usedKeys()) + + const keysInAddExtraTags = mapping.addExtraTags.map(t => t.key) + + const duplicateKeys = keysInAddExtraTags.filter(k => keysInMapping.has(k)) + if (duplicateKeys.length > 0) { + errors.push( + "At " + context + ".mappings[" + i + "]: AddExtraTags overrides a key that is set in the `if`-clause of this mapping. Selecting this answer might thus first set one value (needed to match as answer) and then override it with a different value, resulting in an unsaveable question. The offending `addExtraTags` is " + duplicateKeys.join(", ") + ) + } + } + + + return { + result: json, + errors + }; + } +} + + export class DetectShadowedMappings extends DesugaringStep { private readonly _calculatedTagNames: string[] @@ -449,7 +495,7 @@ export class DetectShadowedMappings extends DesugaringStep { + keyValues.forEach(({k, v}) => { properties[k] = v }) for (let j = 0; j < i; j++) { @@ -492,10 +538,10 @@ export class DetectShadowedMappings extends DesugaringStep { if (json["special"] !== undefined) { errors.push( "At " + - context + - ': detected `special` on the top level. Did you mean `{"render":{ "special": ... }}`' + context + + ': detected `special` on the top level. Did you mean `{"render":{ "special": ... }}`' ) } if (json["group"]) { errors.push( "At " + - context + - ': groups are deprecated, use `"label": ["' + - json["group"] + - '"]` instead' + context + + ': groups are deprecated, use `"label": ["' + + json["group"] + + '"]` instead' ) } const freeformType = json["freeform"]?.["type"] @@ -669,6 +715,7 @@ export class ValidateTagRenderings extends Fuse { super( "Various validation on tagRenderingConfigs", new DetectShadowedMappings(layerConfig), + new DetectConflictingAddExtraTags(), new DetectMappingsWithImages(doesImageExist), new MiscTagRenderingChecks(options) ) @@ -711,9 +758,9 @@ export class ValidateLayer extends DesugaringStep { if (!Constants.priviliged_layers.find((x) => x == json.id)) { errors.push( context + - ": layer " + - json.id + - " uses 'special' as source.osmTags. However, this layer is not a priviliged layer" + ": layer " + + json.id + + " uses 'special' as source.osmTags. However, this layer is not a priviliged layer" ) } } @@ -722,13 +769,13 @@ export class ValidateLayer extends DesugaringStep { if (json.title === undefined && json.source !== "special:library") { errors.push( context + - ": this layer does not have a title defined but it does have tagRenderings. Not having a title will disable the popups, resulting in an unclickable element. Please add a title. If not having a popup is intended and the tagrenderings need to be kept (e.g. in a library layer), set `title: null` to disable this error." + ": this layer does not have a title defined but it does have tagRenderings. Not having a title will disable the popups, resulting in an unclickable element. Please add a title. If not having a popup is intended and the tagrenderings need to be kept (e.g. in a library layer), set `title: null` to disable this error." ) } if (json.title === null) { information.push( context + - ": title is `null`. This results in an element that cannot be clicked - even though tagRenderings is set." + ": title is `null`. This results in an element that cannot be clicked - even though tagRenderings is set." ) } } @@ -755,9 +802,9 @@ export class ValidateLayer extends DesugaringStep { console.log(json.tagRenderings) errors.push( "At " + - context + - ": some tagrenderings have a duplicate id: " + - duplicates.join(", ") + context + + ": some tagrenderings have a duplicate id: " + + duplicates.join(", ") ) } } @@ -775,8 +822,8 @@ export class ValidateLayer extends DesugaringStep { if (json["overpassTags"] !== undefined) { errors.push( "Layer " + - json.id + - 'still uses the old \'overpassTags\'-format. Please use "source": {"osmTags": }\' instead of "overpassTags": (note: this isn\'t your fault, the custom theme generator still spits out the old format)' + json.id + + 'still uses the old \'overpassTags\'-format. Please use "source": {"osmTags": }\' instead of "overpassTags": (note: this isn\'t your fault, the custom theme generator still spits out the old format)' ) } const forbiddenTopLevel = [ @@ -794,18 +841,18 @@ export class ValidateLayer extends DesugaringStep { if (json[forbiddenKey] !== undefined) errors.push( context + - ": layer " + - json.id + - " still has a forbidden key " + - forbiddenKey + ": layer " + + json.id + + " still has a forbidden key " + + forbiddenKey ) } if (json["hideUnderlayingFeaturesMinPercentage"] !== undefined) { errors.push( context + - ": layer " + - json.id + - " contains an old 'hideUnderlayingFeaturesMinPercentage'" + ": layer " + + json.id + + " contains an old 'hideUnderlayingFeaturesMinPercentage'" ) } @@ -822,9 +869,9 @@ export class ValidateLayer extends DesugaringStep { if (this._path != undefined && this._path.indexOf(expected) < 0) { errors.push( "Layer is in an incorrect place. The path is " + - this._path + - ", but expected " + - expected + this._path + + ", but expected " + + expected ) } } @@ -865,6 +912,13 @@ export class ValidateLayer extends DesugaringStep { } } + if (json.filter) { + const r = new On("filter", new Each( new ValidateFilter())).convert(json, context) + warnings.push(...(r.warnings ?? [])) + errors.push(...(r.errors ?? [])) + information.push(...(r.information ?? [])) + } + if (json.tagRenderings !== undefined) { const r = new On( "tagRenderings", @@ -886,9 +940,9 @@ export class ValidateLayer extends DesugaringStep { if (hasCondition?.length > 0) { errors.push( "At " + - context + - ":\n One or more icons in the mapRenderings have a condition set. Don't do this, as this will result in an invisible but clickable element. Use extra filters in the source instead. The offending mapRenderings are:\n" + - JSON.stringify(hasCondition, null, " ") + context + + ":\n One or more icons in the mapRenderings have a condition set. Don't do this, as this will result in an invisible but clickable element. Use extra filters in the source instead. The offending mapRenderings are:\n" + + JSON.stringify(hasCondition, null, " ") ) } } @@ -903,7 +957,7 @@ export class ValidateLayer extends DesugaringStep { const preset = json.presets[i] const tags: { k: string; v: string }[] = new And( preset.tags.map((t) => TagUtils.Tag(t)) - ).asChange({ id: "node/-1" }) + ).asChange({id: "node/-1"}) const properties = {} for (const tag of tags) { properties[tag.k] = tag.v @@ -912,12 +966,12 @@ export class ValidateLayer extends DesugaringStep { if (!doMatch) { errors.push( context + - ".presets[" + - i + - "]: This preset does not match the required tags of this layer. This implies that a newly added point will not show up.\n A newly created point will have properties: " + - JSON.stringify(properties) + - "\n The required tags are: " + - baseTags.asHumanString(false, false, {}) + ".presets[" + + i + + "]: This preset does not match the required tags of this layer. This implies that a newly added point will not show up.\n A newly created point will have properties: " + + JSON.stringify(properties) + + "\n The required tags are: " + + baseTags.asHumanString(false, false, {}) ) } } @@ -949,9 +1003,14 @@ export class ValidateFilter extends DesugaringStep { warnings?: string[] information?: string[] } { + if (typeof filter === "string") { + // Calling another filter, we skip + return {result: filter} + } const errors = [] for (const option of filter.options) { - for (let i = 0; i < option.fields.length; i++) { + + for (let i = 0; i < option.fields?.length ?? 0; i++) { const field = option.fields[i] const type = field.type ?? "string" if (Validators.availableTypes.find((t) => t === type) === undefined) { @@ -962,7 +1021,7 @@ export class ValidateFilter extends DesugaringStep { } } } - return { result: filter, errors } + return {result: filter, errors} } } @@ -991,7 +1050,7 @@ export class DetectDuplicateFilters extends DesugaringStep<{ const warnings: string[] = [] const information: string[] = [] - const { layers, themes } = json + const {layers, themes} = json const perOsmTag = new Map< string, { @@ -1027,7 +1086,7 @@ export class DetectDuplicateFilters extends DesugaringStep<{ return } let msg = "Possible duplicate filter: " + key - for (const { filter, layer, layout } of value) { + for (const {filter, layer, layout} of value) { let id = "" if (layout !== undefined) { id = layout.id + ":" From 3c08c1297423d74348aa83e5932a7fbd94c260e5 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Fri, 28 Jul 2023 14:34:40 +0200 Subject: [PATCH 7/9] Fix: fix #1528: from weblate to theme files did not properly sync --- scripts/generateTranslations.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/generateTranslations.ts b/scripts/generateTranslations.ts index 21460c6b5e..0e8a3036d0 100644 --- a/scripts/generateTranslations.ts +++ b/scripts/generateTranslations.ts @@ -557,7 +557,7 @@ function MergeTranslation(source: any, target: any, language: string, context: s if (context.endsWith(".tagRenderings")) { keyRemapping = new Map() for (const key in target) { - keyRemapping.set(target[key].id, key) + keyRemapping.set(target[key].id ?? target[key].builtin, key) } } From 5d00f3cc6a75a22732ec7ffa63d9335d9d75853c Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Tue, 8 Aug 2023 20:41:18 +0200 Subject: [PATCH 8/9] Fix: fix #1532 --- src/Models/ThemeConfig/TagRenderingConfig.ts | 82 ++++++++++++-------- 1 file changed, 48 insertions(+), 34 deletions(-) diff --git a/src/Models/ThemeConfig/TagRenderingConfig.ts b/src/Models/ThemeConfig/TagRenderingConfig.ts index dbc0ba2f3f..6cd5dc4dc8 100644 --- a/src/Models/ThemeConfig/TagRenderingConfig.ts +++ b/src/Models/ThemeConfig/TagRenderingConfig.ts @@ -58,7 +58,7 @@ export default class TagRenderingConfig { public readonly freeform?: { readonly key: string - readonly type: string + readonly type: ValidatorType readonly placeholder: Translation readonly addExtraTags: UploadableTag[] readonly inline: boolean @@ -133,7 +133,17 @@ export default class TagRenderingConfig { ) { throw `Freeform.addExtraTags should be a list of strings - not a single string (at ${context})` } - const type = json.freeform.type ?? "string" + if ( + json.freeform.type && + Validators.availableTypes.indexOf(json.freeform.type) < 0 + ) { + throw `At ${context}: invalid type, perhaps you meant ${Utils.sortedByLevenshteinDistance( + json.freeform.key, + Validators.availableTypes, + (s) => s + )}` + } + const type: ValidatorType = json.freeform.type ?? "string" let placeholder: Translation = Translations.T(json.freeform.placeholder) if (placeholder === undefined) { @@ -622,7 +632,7 @@ export default class TagRenderingConfig { * * @param singleSelectedMapping (Only used if multiAnswer == false): the single mapping to apply. Use (mappings.length) for the freeform * @param multiSelectedMapping (Only used if multiAnswer == true): all the mappings that must be applied. Set multiSelectedMapping[mappings.length] to use the freeform as well - * @param currentProperties: The current properties of the object for which the question should be answered + * @param currentProperties The current properties of the object for which the question should be answered */ public constructChangeSpecification( freeformValue: string | undefined, @@ -685,38 +695,42 @@ export default class TagRenderingConfig { return undefined } return and - } else { - // Is at least one mapping shown in the answer? - const someMappingIsShown = this.mappings.some((m) => { - if (typeof m.hideInAnswer === "boolean") { - return !m.hideInAnswer - } - const isHidden = m.hideInAnswer.matchesProperties(currentProperties) - return !isHidden - }) - // If all mappings are hidden for the current tags, we can safely assume that we should use the freeform key - const useFreeform = - freeformValue !== undefined && - (singleSelectedMapping === this.mappings.length || !someMappingIsShown) - if (useFreeform) { - return new And([ - new Tag(this.freeform.key, freeformValue), - ...(this.freeform.addExtraTags ?? []), - ]) - } else if (singleSelectedMapping !== undefined) { - return new And([ - this.mappings[singleSelectedMapping].if, - ...(this.mappings[singleSelectedMapping].addExtraTags ?? []), - ]) - } else { - console.warn("TagRenderingConfig.ConstructSpecification has a weird fallback for", { - freeformValue, - singleSelectedMapping, - multiSelectedMapping, - currentProperties, - }) - return undefined + } + + // Is at least one mapping shown in the answer? + const someMappingIsShown = this.mappings.some((m) => { + if (typeof m.hideInAnswer === "boolean") { + return !m.hideInAnswer } + const isHidden = m.hideInAnswer.matchesProperties(currentProperties) + return !isHidden + }) + // If all mappings are hidden for the current tags, we can safely assume that we should use the freeform key + const useFreeform = + freeformValue !== undefined && + (singleSelectedMapping === this.mappings.length || + !someMappingIsShown || + singleSelectedMapping === undefined) + if (useFreeform) { + return new And([ + new Tag(this.freeform.key, freeformValue), + ...(this.freeform.addExtraTags ?? []), + ]) + } else if (singleSelectedMapping !== undefined) { + return new And([ + this.mappings[singleSelectedMapping].if, + ...(this.mappings[singleSelectedMapping].addExtraTags ?? []), + ]) + } else { + console.error("TagRenderingConfig.ConstructSpecification has a weird fallback for", { + freeformValue, + singleSelectedMapping, + multiSelectedMapping, + currentProperties, + useFreeform, + }) + + return undefined } } From 7d5aa725fb319b14cc82f54a35c2601274773d43 Mon Sep 17 00:00:00 2001 From: Pieter Vander Vennet Date: Tue, 8 Aug 2023 20:44:34 +0200 Subject: [PATCH 9/9] Typing: Fix some typing errors --- .../mapcomplete-changes.json | 97 +++++-------------- src/UI/InputElement/ValidatedInput.svelte | 3 +- src/UI/InputElement/Validator.ts | 10 +- .../InputElement/Validators/FloatValidator.ts | 5 +- .../TagRendering/TagRenderingQuestion.svelte | 2 +- 5 files changed, 37 insertions(+), 80 deletions(-) diff --git a/assets/themes/mapcomplete-changes/mapcomplete-changes.json b/assets/themes/mapcomplete-changes/mapcomplete-changes.json index deda66b656..56555e8719 100644 --- a/assets/themes/mapcomplete-changes/mapcomplete-changes.json +++ b/assets/themes/mapcomplete-changes/mapcomplete-changes.json @@ -1,19 +1,13 @@ { "id": "mapcomplete-changes", "title": { - "en": "Changes made with MapComplete", - "de": "Mit MapComplete erstellte Änderungen", - "nl": "Wijzigingen gemaakt met MapComplete" + "en": "Changes made with MapComplete" }, "shortDescription": { - "en": "Show changes made with MapComplete", - "de": "Mit MapComplete erstellte Änderungen anzeigen", - "nl": "Toon wijzigingen gemaakt met MapComplete" + "en": "Shows changes made by MapComplete" }, "description": { - "en": "This maps shows all the changes made with MapComplete", - "de": "Diese Karte zeigt alle mit MapComplete vorgenommenen Änderungen", - "nl": "Deze kaart toont alle wijzigingen die met MapComplete gemaakt werden" + "en": "This maps shows all the changes made with MapComplete" }, "icon": "./assets/svg/logo.svg", "hideFromOverview": true, @@ -26,9 +20,7 @@ { "id": "mapcomplete-changes", "name": { - "en": "Changeset centers", - "de": "Zentrum der Änderungssätze", - "nl": "Centerpunt van changeset" + "en": "Changeset centers" }, "minzoom": 0, "source": { @@ -39,51 +31,41 @@ }, "title": { "render": { - "en": "Changeset for {theme}", - "de": "Änderungssatz für {theme}" + "en": "Changeset for {theme}" } }, "description": { - "en": "Show all MapComplete changes", - "de": "Alle MapComplete-Änderungen anzeigen", - "nl": "Toon alle MapComplete wijzigingen" + "en": "Shows all MapComplete changes" }, "tagRenderings": [ { "id": "show_changeset_id", "render": { - "en": "Changeset {id}", - "de": "Änderungssatz {id}" + "en": "Changeset {id}" } }, { "id": "contributor", "question": { - "en": "Which contributor made this change?", - "de": "Welcher Mitwirkende hat diese Änderung vorgenommen?", - "nl": "Welke bijdrager maakte deze wijziging?" + "en": "What contributor did make this change?" }, "freeform": { "key": "user" }, "render": { - "en": "Change made by {user}", - "de": "Änderung gemacht von {user}", - "nl": "Wijziging gemaakt door {user}" + "en": "Change made by {user}" } }, { "id": "theme-id", "question": { - "en": "What theme was used to make this change?", - "de": "Welches Thema wurde für diese Änderung verwendet?" + "en": "What theme was used to make this change?" }, "freeform": { "key": "theme" }, "render": { - "en": "Change with theme {theme}", - "de": "Geändert mit Thema {theme}" + "en": "Change with theme {theme}" } }, { @@ -92,27 +74,19 @@ "key": "locale" }, "question": { - "en": "What locale (language) was this change made in?", - "de": "In welcher Sprache wurde diese Änderung vorgenommen?", - "nl": "In welke locale (taal) werd deze wijziging gemaakt?" + "en": "What locale (language) was this change made in?" }, "render": { - "en": "User locale is {locale}", - "de": "Usersprache ist {locale}", - "nl": "De gebruikerstaal is {locale}" + "en": "User locale is {locale}" } }, { "id": "host", "render": { - "en": "Change made with {host}", - "de": "Änderung vorgenommen mit {host}", - "nl": "Wijziging gemaakt met {host}" + "en": "Change with with {host}" }, "question": { - "en": "What host (website) was this change made with?", - "de": "Mit welchem Host / welcher Website wurde diese Änderung gemacht?", - "nl": "Met welke host (website) werd deze wijziging gemaakt?" + "en": "What host (website) was this change made with?" }, "freeform": { "key": "host" @@ -133,12 +107,10 @@ { "id": "version", "question": { - "en": "What version of MapComplete was used to make this change?", - "de": "Mit welcher Version von MapComplete wurde diese Änderung gemacht?" + "en": "What version of MapComplete was used to make this change?" }, "render": { - "en": "Made with {editor}", - "de": "Erstellt mit {editor}" + "en": "Made with {editor}" }, "freeform": { "key": "editor" @@ -480,9 +452,7 @@ } ], "question": { - "en": "Theme name contains {search}", - "de": "Themenname enthält {search}", - "nl": "Themenaam bevat {search}" + "en": "Themename contains {search}" } } ] @@ -498,9 +468,7 @@ } ], "question": { - "en": "Made by contributor {search}", - "de": "Erstellt von {search}", - "nl": "Gemaakt door bijdrager {search}" + "en": "Made by contributor {search}" } } ] @@ -516,9 +484,7 @@ } ], "question": { - "en": "Not made by contributor {search}", - "de": "Nicht erstellt von {search}", - "nl": "Niet gemaakt door bijdrager {search}" + "en": "Not made by contributor {search}" } } ] @@ -535,9 +501,7 @@ } ], "question": { - "en": "Made before {search}", - "de": "Erstellt vor {search}", - "nl": "Gemaakt voor {search}" + "en": "Made before {search}" } } ] @@ -554,9 +518,7 @@ } ], "question": { - "en": "Made after {search}", - "de": "Erstellt nach {search}", - "nl": "Gemaakt na {search}" + "en": "Made after {search}" } } ] @@ -572,9 +534,7 @@ } ], "question": { - "en": "User language (iso-code) {search}", - "de": "Benutzersprache (ISO-Code) {search}", - "nl": "De taal van de bijdrager is {search}" + "en": "User language (iso-code) {search}" } } ] @@ -590,9 +550,7 @@ } ], "question": { - "en": "Made with host {search}", - "de": "Erstellt mit Host {search}", - "nl": "Gemaakt met host {search}" + "en": "Made with host {search}" } } ] @@ -603,9 +561,7 @@ { "osmTags": "add-image>0", "question": { - "en": "Changeset added at least one image", - "de": "Changeset fügte mindestens ein Bild hinzu", - "nl": "Changeset bevat minstens één afbeelding" + "en": "Changeset added at least one image" } } ] @@ -620,8 +576,7 @@ { "id": "link_to_more", "render": { - "en": "More statistics can be found here", - "de": "Mehr Statistiken gibt es hier" + "en": "More statistics can be found here" } }, { diff --git a/src/UI/InputElement/ValidatedInput.svelte b/src/UI/InputElement/ValidatedInput.svelte index 3656e819f1..57b702e1d5 100644 --- a/src/UI/InputElement/ValidatedInput.svelte +++ b/src/UI/InputElement/ValidatedInput.svelte @@ -9,7 +9,7 @@ import { Unit } from "../../Models/Unit" import UnitInput from "../Popup/UnitInput.svelte" - export let type: ValidatorType + export let type: ValidatorType export let feedback: UIEventSource | undefined = undefined export let getCountry: () => string | undefined export let placeholder: string | Translation | undefined @@ -63,6 +63,7 @@ } if (unit && isNaN(Number(v))) { + console.debug("Not a number, but a unit is required") value.setData(undefined) return } diff --git a/src/UI/InputElement/Validator.ts b/src/UI/InputElement/Validator.ts index 5172b2433d..e63a98f94a 100644 --- a/src/UI/InputElement/Validator.ts +++ b/src/UI/InputElement/Validator.ts @@ -1,6 +1,6 @@ -import BaseUIElement from "../BaseUIElement" -import { Translation } from "../i18n/Translation" -import Translations from "../i18n/Translations" +import BaseUIElement from "../BaseUIElement"; +import { Translation } from "../i18n/Translation"; +import Translations from "../i18n/Translations"; /** * A 'TextFieldValidator' contains various methods to check and cleanup an entered value or to give feedback. @@ -16,13 +16,13 @@ export abstract class Validator { /** * What HTML-inputmode to use */ - public readonly inputmode?: string + public readonly inputmode?: 'none' | 'text' | 'tel' | 'url' | 'email' | 'numeric' | 'decimal' | 'search' public readonly textArea: boolean constructor( name: string, explanation: string | BaseUIElement, - inputmode?: string, + inputmode?: 'none' | 'text' | 'tel' | 'url' | 'email' | 'numeric' | 'decimal' | 'search', textArea?: false | boolean ) { this.name = name diff --git a/src/UI/InputElement/Validators/FloatValidator.ts b/src/UI/InputElement/Validators/FloatValidator.ts index f984a9fc07..2c3f6adbbc 100644 --- a/src/UI/InputElement/Validators/FloatValidator.ts +++ b/src/UI/InputElement/Validators/FloatValidator.ts @@ -1,11 +1,12 @@ import { Translation } from "../../i18n/Translation" import Translations from "../../i18n/Translations" import { Validator } from "../Validator" +import { ValidatorType } from "../Validators"; export default class FloatValidator extends Validator { - inputmode = "decimal" + inputmode: "decimal" = "decimal" - constructor(name?: string, explanation?: string) { + constructor(name?: ValidatorType, explanation?: string) { super(name ?? "float", explanation ?? "A decimal number", "decimal") } diff --git a/src/UI/Popup/TagRendering/TagRenderingQuestion.svelte b/src/UI/Popup/TagRendering/TagRenderingQuestion.svelte index a746aba3d9..0454187e31 100644 --- a/src/UI/Popup/TagRendering/TagRenderingQuestion.svelte +++ b/src/UI/Popup/TagRendering/TagRenderingQuestion.svelte @@ -69,7 +69,7 @@ export let selectedTags: TagsFilter = undefined let mappings: Mapping[] = config?.mappings - let searchTerm: Store = new UIEventSource("") + let searchTerm: UIEventSource = new UIEventSource("") $: { try {