diff --git a/assets/layers/atm/atm.json b/assets/layers/atm/atm.json
index 9d247dea0f..e873ec3b2c 100644
--- a/assets/layers/atm/atm.json
+++ b/assets/layers/atm/atm.json
@@ -581,25 +581,25 @@
"pt": "Em que línguas este multibanco tem saída de fala?"
},
"render_list_item": {
- "en": "This ATM has speech output in {language():font-bold}",
- "de": "Dieser Geldautomat hat eine Sprachausgabe in {language():font-bold}",
- "nl": "Deze geldautomaat heeft spraak in {language():font-bold}",
- "ca": "Aquest caixer té sortida de veu en {language():font-bold}",
- "cs": "Tento bankomat má řečový výstup v {language():font-bold}",
- "he": "לכספומט הזה יש פלט דיבור ב {language():font-bold}",
- "pt_BR": "Este caixa eletrônico tem saída de fala em {language():font-bold}",
- "es": "Este cajero automático tiene salida de voz en {language():font-bold}",
- "pt": "Este multibanco tem saída de fala em {language():font-bold}"
+ "en": "This ATM has speech output in {language()}",
+ "de": "Dieser Geldautomat hat eine Sprachausgabe in {language()}",
+ "nl": "Deze geldautomaat heeft spraak in {language()}",
+ "ca": "Aquest caixer té sortida de veu en {language()}",
+ "cs": "Tento bankomat má řečový výstup v {language()}",
+ "he": "לכספומט הזה יש פלט דיבור ב {language()}",
+ "pt_BR": "Este caixa eletrônico tem saída de fala em {language()}",
+ "es": "Este cajero automático tiene salida de voz en {language()}",
+ "pt": "Este multibanco tem saída de fala em {language()}"
},
"render_single_language": {
- "en": "This ATM has speech output in {language():font-bold}",
- "de": "Dieser Geldautomat hat eine Sprachausgabe in {language():font-bold}",
- "nl": "Deze automaat heeft spraak in {language():font-bold}",
- "ca": "Aquest caixer té sortida de veu en {language():font-bold}",
- "cs": "Tento bankomat má řečový výstup v {language():font-bold}",
- "he": "לכספומט הזה יש פלט דיבור ב {language():font-bold}",
- "pt_BR": "Este caixa eletrônico tem saída de fala em {language():font-bold}",
- "es": "Este cajero automático tiene salida de voz en {language():font-bold}"
+ "en": "This ATM has speech output in {language()}",
+ "de": "Dieser Geldautomat hat eine Sprachausgabe in {language()}",
+ "nl": "Deze automaat heeft spraak in {language()}",
+ "ca": "Aquest caixer té sortida de veu en {language()}",
+ "cs": "Tento bankomat má řečový výstup v {language()}",
+ "he": "לכספומט הזה יש פלט דיבור ב {language()}",
+ "pt_BR": "Este caixa eletrônico tem saída de fala em {language()}",
+ "es": "Este cajero automático tiene salida de voz en {language()}"
}
}
}
diff --git a/assets/layers/elevator/elevator.json b/assets/layers/elevator/elevator.json
index a6ad920151..6d4fa23178 100644
--- a/assets/layers/elevator/elevator.json
+++ b/assets/layers/elevator/elevator.json
@@ -267,18 +267,18 @@
"cs": "Ve kterých jazycích má tento výtah hmatové písmo (braillovo písmo)?"
},
"render_list_item": {
- "en": "This elevator has tactile writing in {language():font-bold}",
- "de": "Der Aufzug hat taktile Schrift in {language():font-bold}",
- "nl": "Deze lift heeft voelbaar schrift in het {language():font-bold}",
- "ca": "Aquest ascensor té l'escriptura tàctil en {language():font-bold}",
- "cs": "Tento výtah má hmatové písmo v {language():font-bold}"
+ "en": "This elevator has tactile writing in {language()}",
+ "de": "Der Aufzug hat taktile Schrift in {language()}",
+ "nl": "Deze lift heeft voelbaar schrift in het {language()}",
+ "ca": "Aquest ascensor té l'escriptura tàctil en {language()}",
+ "cs": "Tento výtah má hmatové písmo v {language()}"
},
"render_single_language": {
- "en": "This elevator has tactile writing in {language():font-bold}",
- "de": "Der Aufzug hat taktile Schrift in {language():font-bold}",
- "nl": "Deze lift heeft voelbaar schrift in het {language():font-bold}",
- "ca": "Aquest ascensor té l'escriptura tàctil en {language():font-bold}",
- "cs": "Tento výtah má hmatové písmo v {language():font-bold}"
+ "en": "This elevator has tactile writing in {language()}",
+ "de": "Der Aufzug hat taktile Schrift in {language()}",
+ "nl": "Deze lift heeft voelbaar schrift in het {language()}",
+ "ca": "Aquest ascensor té l'escriptura tàctil en {language()}",
+ "cs": "Tento výtah má hmatové písmo v {language()}"
}
}
}
@@ -330,18 +330,18 @@
"cs": "Ve kterých jazycích má tento výtah hlasový výstup?"
},
"render_list_item": {
- "en": "This elevator has speech output in {language():font-bold}",
- "nl": "Deze lift heeft gesproken tekst in het {language():font-bold}",
- "de": "Der Aufzug hat eine Sprachausgabe in {language():font-bold}",
- "ca": "Aquest ascensor té sortida de veu en {language():font-bold}",
- "cs": "Tento výtah má hlasový výstup v {language():font-bold}"
+ "en": "This elevator has speech output in {language()}",
+ "nl": "Deze lift heeft gesproken tekst in het {language()}",
+ "de": "Der Aufzug hat eine Sprachausgabe in {language()}",
+ "ca": "Aquest ascensor té sortida de veu en {language()}",
+ "cs": "Tento výtah má hlasový výstup v {language()}"
},
"render_single_language": {
- "en": "This elevator has speech output in {language():font-bold}",
- "nl": "Deze lift heeft gesproken tekst in het {language():font-bold}",
- "de": "Der Aufzug hat eine Sprachausgabe in {language():font-bold}",
- "ca": "Aquest ascensor té sortida de veu en {language():font-bold}",
- "cs": "Tento výtah má hlasový výstup v {language():font-bold}"
+ "en": "This elevator has speech output in {language()}",
+ "nl": "Deze lift heeft gesproken tekst in het {language()}",
+ "de": "Der Aufzug hat eine Sprachausgabe in {language()}",
+ "ca": "Aquest ascensor té sortida de veu en {language()}",
+ "cs": "Tento výtah má hlasový výstup v {language()}"
}
}
}
diff --git a/assets/layers/school/school.json b/assets/layers/school/school.json
index c8d26be0ec..07ef243ced 100644
--- a/assets/layers/school/school.json
+++ b/assets/layers/school/school.json
@@ -435,12 +435,12 @@
"cs": "V této škole se používají následující jazyky:{list()}"
},
"render_single_language": {
- "en": "{language():font-bold} is the main language of this school",
- "de": "{language():font-bold} ist die Hauptsprache der Schule",
- "ca": "{language():font-bold} és la llengua principal d'aquesta escola",
- "fr": "{language():font-bold} est la langue principale dans cette école",
- "pl": "Język {language():font-bold} jest głównym językiem używanym w tej szkole",
- "cs": "{language():font-bold} je hlavním jazykem této školy"
+ "en": "{language()} is the main language of this school",
+ "de": "{language()} ist die Hauptsprache der Schule",
+ "ca": "{language()} és la llengua principal d'aquesta escola",
+ "fr": "{language()} est la langue principale dans cette école",
+ "pl": "Język {language()} jest głównym językiem używanym w tej szkole",
+ "cs": "{language()} je hlavním jazykem této školy"
},
"question": {
"en": "What is the main language of this school?
What language is spoken with the students in non-language related courses and with the administration?
",
diff --git a/assets/layers/stairs/stairs.json b/assets/layers/stairs/stairs.json
index 8e55fe971c..c51fbf6a50 100644
--- a/assets/layers/stairs/stairs.json
+++ b/assets/layers/stairs/stairs.json
@@ -205,18 +205,18 @@
"cs": "Ve kterých jazycích existuje hmatové písmo (braillské písmo) pro navigaci? "
},
"render_list_item": {
- "en": "These stairs have tactile writing in {language():font-bold}",
- "de": "Die Treppe hat taktile Schrift in {language():font-bold}",
- "nl": "Deze trap heeft voelbaar schrijft in {language():font-bold}",
- "ca": "Aquestes escales tenen escriptura tàctil en {language():font-bold}",
- "cs": "Tyto schody mají hmatové písmo v {language():font-bold}"
+ "en": "These stairs have tactile writing in {language()}",
+ "de": "Die Treppe hat taktile Schrift in {language()}",
+ "nl": "Deze trap heeft voelbaar schrijft in {language()}",
+ "ca": "Aquestes escales tenen escriptura tàctil en {language()}",
+ "cs": "Tyto schody mají hmatové písmo v {language()}"
},
"render_single_language": {
- "en": "These stairs have tactile writing in {language():font-bold}",
- "de": "Die Treppe hat taktile Schrift in {language():font-bold}",
- "nl": "Deze trap heeft voelbaar schrijft in {language():font-bold}",
- "ca": "Aquestes escales tenen escriptura tàctil en {language():font-bold}",
- "cs": "Tyto schody mají hmatové písmo v {language():font-bold}"
+ "en": "These stairs have tactile writing in {language()}",
+ "de": "Die Treppe hat taktile Schrift in {language()}",
+ "nl": "Deze trap heeft voelbaar schrijft in {language()}",
+ "ca": "Aquestes escales tenen escriptura tàctil en {language()}",
+ "cs": "Tyto schody mají hmatové písmo v {language()}"
}
}
}
diff --git a/langs/layers/ca.json b/langs/layers/ca.json
index 4653df83b9..015d90e7a6 100644
--- a/langs/layers/ca.json
+++ b/langs/layers/ca.json
@@ -35,16 +35,6 @@
"1": {
"title": "un mupi"
},
- "10": {
- "description": "S'utilitza per a cartells publicitaris, rètols de neó, logotips i cartells en entrades institucionals",
- "title": "un lletrer"
- },
- "11": {
- "title": "una escupltura"
- },
- "12": {
- "title": "una paret pintada"
- },
"2": {
"title": "un mupi sobre la paret"
},
@@ -71,6 +61,16 @@
},
"9": {
"title": "un tòtem"
+ },
+ "10": {
+ "description": "S'utilitza per a cartells publicitaris, rètols de neó, logotips i cartells en entrades institucionals",
+ "title": "un lletrer"
+ },
+ "11": {
+ "title": "una escupltura"
+ },
+ "12": {
+ "title": "una paret pintada"
}
},
"tagRenderings": {
@@ -165,9 +165,6 @@
"1": {
"then": "Açò és un tauló d'anunis"
},
- "10": {
- "then": "Açò és una paret pintada"
- },
"2": {
"then": "Açò és una columna"
},
@@ -191,6 +188,9 @@
},
"9": {
"then": "Açò és un tòtem"
+ },
+ "10": {
+ "then": "Açò és una paret pintada"
}
},
"question": "Quin tipus d'element publicitari és aquest?",
@@ -205,9 +205,6 @@
"1": {
"then": "Tauló d'anuncis"
},
- "10": {
- "then": "Paret Pintada"
- },
"2": {
"then": "Mupi"
},
@@ -231,6 +228,9 @@
},
"9": {
"then": "Tòtem"
+ },
+ "10": {
+ "then": "Paret Pintada"
}
}
}
@@ -351,15 +351,6 @@
"1": {
"then": "Mural"
},
- "10": {
- "then": "Azulejo (Rajoles decoratives espanyoles i portugueses)"
- },
- "11": {
- "then": "Enrajolat"
- },
- "12": {
- "then": "Tallat a la fusta"
- },
"2": {
"then": "Pintura"
},
@@ -383,6 +374,15 @@
},
"9": {
"then": "Relleu"
+ },
+ "10": {
+ "then": "Azulejo (Rajoles decoratives espanyoles i portugueses)"
+ },
+ "11": {
+ "then": "Enrajolat"
+ },
+ "12": {
+ "then": "Tallat a la fusta"
}
},
"question": "Quin tipus d'obra és aquesta peça?",
@@ -528,8 +528,8 @@
"render": {
"special": {
"question": "En quins idiomes té sortida de veu aquest caixer?",
- "render_list_item": "Aquest caixer té sortida de veu en {language():font-bold}",
- "render_single_language": "Aquest caixer té sortida de veu en {language():font-bold}"
+ "render_list_item": "Aquest caixer té sortida de veu en {language()}",
+ "render_single_language": "Aquest caixer té sortida de veu en {language()}"
}
}
}
@@ -1920,30 +1920,6 @@
"1": {
"then": "Endoll de paret Schuko sense pin a terra (CEE7/4 tipus F)"
},
- "10": {
- "then": "CSS Tipus 1 (també conegut com a Tipus 1 Combo)"
- },
- "11": {
- "then": "CSS Tipus 1 (també conegut com a Tipus 1 Combo)"
- },
- "12": {
- "then": "Supercarregador de Tesla"
- },
- "13": {
- "then": "Supercarregador de Tesla"
- },
- "14": {
- "then": "Tipus 2 (mennekes)"
- },
- "15": {
- "then": "Tipus 2 (mennekes)"
- },
- "16": {
- "then": "CSS Tipus 2 (mennekes)"
- },
- "17": {
- "then": "CSS Tipus 2 (mennekes)"
- },
"2": {
"then": "Endoll de paret Europeu amb pin a terra (CEE7/4 tipus E)"
},
@@ -1967,6 +1943,30 @@
},
"9": {
"then": "Tipus 1 sense cable(J1772)"
+ },
+ "10": {
+ "then": "CSS Tipus 1 (també conegut com a Tipus 1 Combo)"
+ },
+ "11": {
+ "then": "CSS Tipus 1 (també conegut com a Tipus 1 Combo)"
+ },
+ "12": {
+ "then": "Supercarregador de Tesla"
+ },
+ "13": {
+ "then": "Supercarregador de Tesla"
+ },
+ "14": {
+ "then": "Tipus 2 (mennekes)"
+ },
+ "15": {
+ "then": "Tipus 2 (mennekes)"
+ },
+ "16": {
+ "then": "CSS Tipus 2 (mennekes)"
+ },
+ "17": {
+ "then": "CSS Tipus 2 (mennekes)"
}
}
},
@@ -2112,13 +2112,6 @@
}
}
}
- },
- "title": {
- "mappings": {
- "1": {
- "then": "Estació de càrrega per a cotxes"
- }
- }
}
},
"climbing": {
@@ -2643,9 +2636,6 @@
"1": {
"then": "Aquesta via ciclista està pavimentada"
},
- "10": {
- "then": "Aquesta via ciclista està feta de grava fina"
- },
"2": {
"then": "Aquesta via ciclista està feta d'asfalt"
},
@@ -2669,6 +2659,9 @@
},
"9": {
"then": "Aquesta via ciclista està feta de grava"
+ },
+ "10": {
+ "then": "Aquesta via ciclista està feta de grava fina"
}
},
"question": "De quina superfície està fet aquesta via ciclista?",
@@ -2714,9 +2707,6 @@
"1": {
"then": "Aquest carril bici està pavimentat"
},
- "10": {
- "then": "Aquesta via ciclista està feta de gravilla"
- },
"2": {
"then": "Aquest carril bici està fet d'asfalt"
},
@@ -2728,6 +2718,9 @@
},
"9": {
"then": "Aquesta via ciclista està feta de grava"
+ },
+ "10": {
+ "then": "Aquesta via ciclista està feta de gravilla"
}
},
"question": "De què està feta la superfície d'aquest carrer?",
@@ -3227,8 +3220,8 @@
"render": {
"special": {
"question": "Aquest ascensor en quins idiomes té sortida de veu?",
- "render_list_item": "Aquest ascensor té sortida de veu en {language():font-bold}",
- "render_single_language": "Aquest ascensor té sortida de veu en {language():font-bold}"
+ "render_list_item": "Aquest ascensor té sortida de veu en {language()}",
+ "render_single_language": "Aquest ascensor té sortida de veu en {language()}"
}
}
},
@@ -3250,8 +3243,8 @@
"render": {
"special": {
"question": "Aquest ascensor en quins idiomes té l'escriptura tàctil (braille)?",
- "render_list_item": "Aquest ascensor té l'escriptura tàctil en {language():font-bold}",
- "render_single_language": "Aquest ascensor té l'escriptura tàctil en {language():font-bold}"
+ "render_list_item": "Aquest ascensor té l'escriptura tàctil en {language()}",
+ "render_single_language": "Aquest ascensor té l'escriptura tàctil en {language()}"
}
}
}
@@ -3746,21 +3739,6 @@
"1": {
"then": "Aquesta estació de fitness té un cartell amb instruccions per a un exercici concret."
},
- "10": {
- "then": "Aquesta estació de gimnàs té esglaons."
- },
- "11": {
- "then": "Aquesta estació de fitness disposa de cons per fer salts de granota."
- },
- "12": {
- "then": "Aquesta estació de fitness té bigues per saltar."
- },
- "13": {
- "then": "Aquesta estació de fitness té obstacles per a travesar."
- },
- "14": {
- "then": "Aquesta estació de fitness té una paret per enfilar-se."
- },
"2": {
"then": "Aquesta estació de fitness té una instal·lació per fer abdominals."
},
@@ -3784,6 +3762,21 @@
},
"9": {
"then": "Aquesta estació de fitness té llocs per fer exercicis d'eslàlom."
+ },
+ "10": {
+ "then": "Aquesta estació de gimnàs té esglaons."
+ },
+ "11": {
+ "then": "Aquesta estació de fitness disposa de cons per fer salts de granota."
+ },
+ "12": {
+ "then": "Aquesta estació de fitness té bigues per saltar."
+ },
+ "13": {
+ "then": "Aquesta estació de fitness té obstacles per a travesar."
+ },
+ "14": {
+ "then": "Aquesta estació de fitness té una paret per enfilar-se."
}
}
}
@@ -3902,21 +3895,6 @@
"1": {
"then": "Això és una fregiduria"
},
- "10": {
- "then": "Aquí es serveixen plats xinesos"
- },
- "11": {
- "then": "Aquí es serveixen plats grecs"
- },
- "12": {
- "then": "Aquí es serveixen plats indis"
- },
- "13": {
- "then": "Aquí es serveixen plats turcs"
- },
- "14": {
- "then": "Aquí es serveixen plats tailandesos"
- },
"2": {
"then": "Principalment serveix pasta"
},
@@ -3940,6 +3918,21 @@
},
"9": {
"then": "Aquí es serveixen plats francesos"
+ },
+ "10": {
+ "then": "Aquí es serveixen plats xinesos"
+ },
+ "11": {
+ "then": "Aquí es serveixen plats grecs"
+ },
+ "12": {
+ "then": "Aquí es serveixen plats indis"
+ },
+ "13": {
+ "then": "Aquí es serveixen plats turcs"
+ },
+ "14": {
+ "then": "Aquí es serveixen plats tailandesos"
}
},
"question": "Quin tipus de menjar es serveix aquí?",
@@ -4492,24 +4485,9 @@
"1": {
"then": "Açò és un auditori"
},
- "10": {
- "then": "Açò és un laboratori"
- },
- "14": {
- "then": "Açò és una oficina"
- },
- "16": {
- "then": "Açò és un restaurant"
- },
- "19": {
- "then": "Açò és un magatzem"
- },
"2": {
"then": "Açò és un dormitori"
},
- "22": {
- "then": "Açò és una sala d'espera"
- },
"3": {
"then": "Açò és una capella"
},
@@ -4527,6 +4505,21 @@
},
"9": {
"then": "Açò és una cuina"
+ },
+ "10": {
+ "then": "Açò és un laboratori"
+ },
+ "14": {
+ "then": "Açò és una oficina"
+ },
+ "16": {
+ "then": "Açò és un restaurant"
+ },
+ "19": {
+ "then": "Açò és un magatzem"
+ },
+ "22": {
+ "then": "Açò és una sala d'espera"
}
},
"question": "Quin tipus d'habitació és aquesta?"
@@ -5128,19 +5121,6 @@
}
}
},
- "10": {
- "options": {
- "0": {
- "question": "Totes les notes"
- },
- "1": {
- "question": "Oculta les notes d'importació"
- },
- "2": {
- "question": "Mostrar només les notes d'importació"
- }
- }
- },
"2": {
"options": {
"0": {
@@ -5196,6 +5176,19 @@
"question": "Sols mostra les notes obertes"
}
}
+ },
+ "10": {
+ "options": {
+ "0": {
+ "question": "Totes les notes"
+ },
+ "1": {
+ "question": "Oculta les notes d'importació"
+ },
+ "2": {
+ "question": "Mostrar només les notes d'importació"
+ }
+ }
}
},
"name": "Notes d'OpenStreetMap",
@@ -5495,15 +5488,6 @@
"1": {
"then": "Aquesta és una plaça d'aparcament normal."
},
- "10": {
- "then": "Es tracta d'una plaça d'aparcament reservada per a pares amb fills."
- },
- "11": {
- "then": "Es tracta d'una plaça d'aparcament reservada al personal."
- },
- "12": {
- "then": "Aquest espai d'aparcament està reservat per a taxi."
- },
"2": {
"then": "Aquesta és una plaça d'aparcament per a minusvàlids."
},
@@ -5521,6 +5505,15 @@
},
"9": {
"then": "Es tracta d'una plaça d'aparcament reservada per a motos."
+ },
+ "10": {
+ "then": "Es tracta d'una plaça d'aparcament reservada per a pares amb fills."
+ },
+ "11": {
+ "then": "Es tracta d'una plaça d'aparcament reservada al personal."
+ },
+ "12": {
+ "then": "Aquest espai d'aparcament està reservat per a taxi."
}
},
"question": "Quin tipus d'espai d'aparcament és aquest?"
@@ -6095,21 +6088,6 @@
"1": {
"then": "S'accepten monedes de 2 cèntims"
},
- "10": {
- "then": "S'accepten monedes de 20 cèntims"
- },
- "11": {
- "then": "S'accepten monedes de ½ franc"
- },
- "12": {
- "then": "S'accepten monedes d'1 franc"
- },
- "13": {
- "then": "S'accepten monedes de 2 francs"
- },
- "14": {
- "then": "S'accepten monedes de 5 francs"
- },
"2": {
"then": "S'accepten monedes de 5 cèntims"
},
@@ -6133,6 +6111,21 @@
},
"9": {
"then": "S'accepten monedes de 10 cèntims"
+ },
+ "10": {
+ "then": "S'accepten monedes de 20 cèntims"
+ },
+ "11": {
+ "then": "S'accepten monedes de ½ franc"
+ },
+ "12": {
+ "then": "S'accepten monedes d'1 franc"
+ },
+ "13": {
+ "then": "S'accepten monedes de 2 francs"
+ },
+ "14": {
+ "then": "S'accepten monedes de 5 francs"
}
},
"question": "Quines monedes es poden utilitzar per a pagar aquí?"
@@ -6145,15 +6138,6 @@
"1": {
"then": "S'accepten bitllets de 10 euros"
},
- "10": {
- "then": "S'accepten bitllets de 100 francs"
- },
- "11": {
- "then": "S'accepten bitllets de 200 francs"
- },
- "12": {
- "then": "S'accepten bitllets de 1000 francs"
- },
"2": {
"then": "S'accepten bitllets de 20 euros"
},
@@ -6177,6 +6161,15 @@
},
"9": {
"then": "S'accepten bitllets de 50 francs"
+ },
+ "10": {
+ "then": "S'accepten bitllets de 100 francs"
+ },
+ "11": {
+ "then": "S'accepten bitllets de 200 francs"
+ },
+ "12": {
+ "then": "S'accepten bitllets de 1000 francs"
}
},
"question": "Amb quins bitllets pot pagar aquí?"
@@ -6531,6 +6524,30 @@
"1": {
"question": "Reciclatge de piles"
},
+ "2": {
+ "question": "Reciclatge de cartrons de begudes"
+ },
+ "3": {
+ "question": "Reciclatge de llaunes"
+ },
+ "4": {
+ "question": "Reciclatge de roba"
+ },
+ "5": {
+ "question": "Reciclatge d'oli de cuina"
+ },
+ "6": {
+ "question": "Reciclatge d'oli de motor"
+ },
+ "7": {
+ "question": "Reciclatge de tubs fluorescents"
+ },
+ "8": {
+ "question": "Reciclatge de residus verds"
+ },
+ "9": {
+ "question": "Reciclatge d'ampolles de vidre"
+ },
"10": {
"question": "Reciclatge de vidre"
},
@@ -6561,35 +6578,11 @@
"19": {
"question": "Reciclatge del rebuig"
},
- "2": {
- "question": "Reciclatge de cartrons de begudes"
- },
"20": {
"question": "Reciclatge de cartutxos d'impressora"
},
"21": {
"question": "Reciclatge de bicicletes"
- },
- "3": {
- "question": "Reciclatge de llaunes"
- },
- "4": {
- "question": "Reciclatge de roba"
- },
- "5": {
- "question": "Reciclatge d'oli de cuina"
- },
- "6": {
- "question": "Reciclatge d'oli de motor"
- },
- "7": {
- "question": "Reciclatge de tubs fluorescents"
- },
- "8": {
- "question": "Reciclatge de residus verds"
- },
- "9": {
- "question": "Reciclatge d'ampolles de vidre"
}
}
},
@@ -6657,6 +6650,30 @@
"1": {
"then": "Aquí es poden reciclar els cartons de begudes"
},
+ "2": {
+ "then": "Aquí es poden reciclar llaunes"
+ },
+ "3": {
+ "then": "Aquí es pot reciclar roba"
+ },
+ "4": {
+ "then": "Aquí es pot reciclar oli de cuina"
+ },
+ "5": {
+ "then": "Aquí es pot reciclar oli de motor"
+ },
+ "6": {
+ "then": "Aquí es poden reciclar tub fluroescents"
+ },
+ "7": {
+ "then": "Aquí es poden reciclar residus verds"
+ },
+ "8": {
+ "then": "Ací es poden reciclar residus orgànics"
+ },
+ "9": {
+ "then": "Aquí es poden reciclar ampolles de vidre"
+ },
"10": {
"then": "Aquí es pot reciclar vidre"
},
@@ -6687,9 +6704,6 @@
"19": {
"then": "Aquí es poden reciclar sabates"
},
- "2": {
- "then": "Aquí es poden reciclar llaunes"
- },
"20": {
"then": "Aquí es poden reciclar petits electrodomèstics"
},
@@ -6704,27 +6718,6 @@
},
"24": {
"then": "Aquí es poden reciclar bicicletes"
- },
- "3": {
- "then": "Aquí es pot reciclar roba"
- },
- "4": {
- "then": "Aquí es pot reciclar oli de cuina"
- },
- "5": {
- "then": "Aquí es pot reciclar oli de motor"
- },
- "6": {
- "then": "Aquí es poden reciclar tub fluroescents"
- },
- "7": {
- "then": "Aquí es poden reciclar residus verds"
- },
- "8": {
- "then": "Ací es poden reciclar residus orgànics"
- },
- "9": {
- "then": "Aquí es poden reciclar ampolles de vidre"
}
},
"question": "Què es pot reciclar aquí?"
@@ -6835,7 +6828,7 @@
"no_known_languages": "La llengua principal d'aquesta escola és desconeguda",
"question": "Quina és la llengua principal d'aquesta escola?
Quina llengua es parla amb els estudiants en classes no relacionades amb la llengua i l'administració?
",
"render_all": "En aquesta escola s'utilitzen els idiomes següents:{list()}",
- "render_single_language": "{language():font-bold} és la llengua principal d'aquesta escola"
+ "render_single_language": "{language()} és la llengua principal d'aquesta escola"
}
}
},
@@ -7381,8 +7374,8 @@
"render": {
"special": {
"question": "En quins idiomes hi ha escriptura tàctil (braille) per a la navegació? ",
- "render_list_item": "Aquestes escales tenen escriptura tàctil en {language():font-bold}",
- "render_single_language": "Aquestes escales tenen escriptura tàctil en {language():font-bold}"
+ "render_list_item": "Aquestes escales tenen escriptura tàctil en {language()}",
+ "render_single_language": "Aquestes escales tenen escriptura tàctil en {language()}"
}
}
}
@@ -7472,12 +7465,6 @@
"1": {
"then": "Aquest fanal utilitza LED"
},
- "10": {
- "then": "Aquest fanal utilitza làmpades de sodi d'alta pressió (taronja amb blanc)"
- },
- "11": {
- "then": "Aquest fanal s'il·lumina amb gas"
- },
"2": {
"then": "Aquest fanal utilitza il·luminació incandescent"
},
@@ -7501,6 +7488,12 @@
},
"9": {
"then": "Aquest fanal utilitza làmpades de sodi de baixa pressió (taronja monocroma)"
+ },
+ "10": {
+ "then": "Aquest fanal utilitza làmpades de sodi d'alta pressió (taronja amb blanc)"
+ },
+ "11": {
+ "then": "Aquest fanal s'il·lumina amb gas"
}
},
"question": "Quin tipus d'il·luminació utilitza aquest fanal?"
@@ -8705,6 +8698,30 @@
"1": {
"question": "Venda de begudes"
},
+ "2": {
+ "question": "Venda de llaminadures"
+ },
+ "3": {
+ "question": "Venda de menjar"
+ },
+ "4": {
+ "question": "Venda de tabaco"
+ },
+ "5": {
+ "question": "Venda de preservatius"
+ },
+ "6": {
+ "question": "Venda de cafè"
+ },
+ "7": {
+ "question": "Venda d'aigua"
+ },
+ "8": {
+ "question": "Venda de diaris"
+ },
+ "9": {
+ "question": "Venda de càmeres interiors de bicicletes"
+ },
"10": {
"question": "Venda de llet"
},
@@ -8735,9 +8752,6 @@
"19": {
"question": "Venda de flors"
},
- "2": {
- "question": "Venda de llaminadures"
- },
"20": {
"question": "Venda de tiquets d'aparcament"
},
@@ -8761,27 +8775,6 @@
},
"27": {
"question": "Venda de cadenat per a bicicletes"
- },
- "3": {
- "question": "Venda de menjar"
- },
- "4": {
- "question": "Venda de tabaco"
- },
- "5": {
- "question": "Venda de preservatius"
- },
- "6": {
- "question": "Venda de cafè"
- },
- "7": {
- "question": "Venda d'aigua"
- },
- "8": {
- "question": "Venda de diaris"
- },
- "9": {
- "question": "Venda de càmeres interiors de bicicletes"
}
}
}
@@ -8828,6 +8821,30 @@
"1": {
"then": "Es venen llaminadures"
},
+ "2": {
+ "then": "Es ven menjar"
+ },
+ "3": {
+ "then": "Es ven tabaco"
+ },
+ "4": {
+ "then": "Es venen preservatius"
+ },
+ "5": {
+ "then": "Es ven cafè"
+ },
+ "6": {
+ "then": "Es ven aigua"
+ },
+ "7": {
+ "then": "Es venen diaris"
+ },
+ "8": {
+ "then": "Es venen càmeres interiors de bicicletes"
+ },
+ "9": {
+ "then": "Es ven llet"
+ },
"10": {
"then": "Es ven pa"
},
@@ -8858,9 +8875,6 @@
"19": {
"then": "Es venen tiquets d'aparcament"
},
- "2": {
- "then": "Es ven menjar"
- },
"20": {
"then": "Es venen cèntims premsats"
},
@@ -8881,27 +8895,6 @@
},
"26": {
"then": "Es venen cadenats per a bicicletes"
- },
- "3": {
- "then": "Es ven tabaco"
- },
- "4": {
- "then": "Es venen preservatius"
- },
- "5": {
- "then": "Es ven cafè"
- },
- "6": {
- "then": "Es ven aigua"
- },
- "7": {
- "then": "Es venen diaris"
- },
- "8": {
- "then": "Es venen càmeres interiors de bicicletes"
- },
- "9": {
- "then": "Es ven llet"
}
},
"question": "Que ven aquesta màquina expenedora?",
@@ -9193,4 +9186,4 @@
"render": "Turbina eòlica"
}
}
-}
+}
\ No newline at end of file
diff --git a/langs/layers/cs.json b/langs/layers/cs.json
index 79561d7cae..8b99ac086f 100644
--- a/langs/layers/cs.json
+++ b/langs/layers/cs.json
@@ -489,8 +489,8 @@
"render": {
"special": {
"question": "V jakých jazycích má tento bankomat řečový výstup?",
- "render_list_item": "Tento bankomat má řečový výstup v {language():font-bold}",
- "render_single_language": "Tento bankomat má řečový výstup v {language():font-bold}"
+ "render_list_item": "Tento bankomat má řečový výstup v {language()}",
+ "render_single_language": "Tento bankomat má řečový výstup v {language()}"
}
}
}
@@ -3269,8 +3269,8 @@
"render": {
"special": {
"question": "Ve kterých jazycích má tento výtah hlasový výstup?",
- "render_list_item": "Tento výtah má hlasový výstup v {language():font-bold}",
- "render_single_language": "Tento výtah má hlasový výstup v {language():font-bold}"
+ "render_list_item": "Tento výtah má hlasový výstup v {language()}",
+ "render_single_language": "Tento výtah má hlasový výstup v {language()}"
}
}
},
@@ -3301,8 +3301,8 @@
"render": {
"special": {
"question": "Ve kterých jazycích má tento výtah hmatové písmo (braillovo písmo)?",
- "render_list_item": "Tento výtah má hmatové písmo v {language():font-bold}",
- "render_single_language": "Tento výtah má hmatové písmo v {language():font-bold}"
+ "render_list_item": "Tento výtah má hmatové písmo v {language()}",
+ "render_single_language": "Tento výtah má hmatové písmo v {language()}"
}
}
}
@@ -7113,7 +7113,7 @@
"no_known_languages": "Hlavní jazyk této školy není znám",
"question": "Jaký je hlavní jazyk této školy?
Jakým jazykem se mluví se studenty v nejazykových kurzech a administrativou?
",
"render_all": "V této škole se používají následující jazyky:{list()}",
- "render_single_language": "{language():font-bold} je hlavním jazykem této školy"
+ "render_single_language": "{language()} je hlavním jazykem této školy"
}
}
},
@@ -7699,8 +7699,8 @@
"render": {
"special": {
"question": "Ve kterých jazycích existuje hmatové písmo (braillské písmo) pro navigaci? ",
- "render_list_item": "Tyto schody mají hmatové písmo v {language():font-bold}",
- "render_single_language": "Tyto schody mají hmatové písmo v {language():font-bold}"
+ "render_list_item": "Tyto schody mají hmatové písmo v {language()}",
+ "render_single_language": "Tyto schody mají hmatové písmo v {language()}"
}
}
}
diff --git a/langs/layers/de.json b/langs/layers/de.json
index d5cb439c84..a74db0403d 100644
--- a/langs/layers/de.json
+++ b/langs/layers/de.json
@@ -530,8 +530,8 @@
"render": {
"special": {
"question": "In welchen Sprachen hat dieser Geldautomat eine Sprachausgabe?",
- "render_list_item": "Dieser Geldautomat hat eine Sprachausgabe in {language():font-bold}",
- "render_single_language": "Dieser Geldautomat hat eine Sprachausgabe in {language():font-bold}"
+ "render_list_item": "Dieser Geldautomat hat eine Sprachausgabe in {language()}",
+ "render_single_language": "Dieser Geldautomat hat eine Sprachausgabe in {language()}"
}
}
}
@@ -3859,8 +3859,8 @@
"render": {
"special": {
"question": "In welchen Sprachen verfügt der Aufzug über eine Sprachausgabe?",
- "render_list_item": "Der Aufzug hat eine Sprachausgabe in {language():font-bold}",
- "render_single_language": "Der Aufzug hat eine Sprachausgabe in {language():font-bold}"
+ "render_list_item": "Der Aufzug hat eine Sprachausgabe in {language()}",
+ "render_single_language": "Der Aufzug hat eine Sprachausgabe in {language()}"
}
}
},
@@ -3891,8 +3891,8 @@
"render": {
"special": {
"question": "In welchen Sprachen hat der Aufzug taktile Schrift (Braille)?",
- "render_list_item": "Der Aufzug hat taktile Schrift in {language():font-bold}",
- "render_single_language": "Der Aufzug hat taktile Schrift in {language():font-bold}"
+ "render_list_item": "Der Aufzug hat taktile Schrift in {language()}",
+ "render_single_language": "Der Aufzug hat taktile Schrift in {language()}"
}
}
}
@@ -7949,7 +7949,7 @@
"no_known_languages": "Die Unterrichtssprache der Schule ist unbekannt",
"question": "Was ist die Hauptsprache dieser Schule?
Welche Sprache wird mit den Schülern in den nicht sprachbezogenen Kursen und mit der Verwaltung gesprochen?
",
"render_all": "Folgende Sprachen werden in der Schule verwendet:{list()}",
- "render_single_language": "{language():font-bold} ist die Hauptsprache der Schule"
+ "render_single_language": "{language()} ist die Hauptsprache der Schule"
}
}
},
@@ -8620,8 +8620,8 @@
"render": {
"special": {
"question": "In welchen Sprachen gibt es taktile Schrift (Braille) für die Navigation? ",
- "render_list_item": "Die Treppe hat taktile Schrift in {language():font-bold}",
- "render_single_language": "Die Treppe hat taktile Schrift in {language():font-bold}"
+ "render_list_item": "Die Treppe hat taktile Schrift in {language()}",
+ "render_single_language": "Die Treppe hat taktile Schrift in {language()}"
}
}
}
diff --git a/langs/layers/en.json b/langs/layers/en.json
index 250ee88dbe..58b29662f5 100644
--- a/langs/layers/en.json
+++ b/langs/layers/en.json
@@ -530,8 +530,8 @@
"render": {
"special": {
"question": "In which languages does this ATM have speech output?",
- "render_list_item": "This ATM has speech output in {language():font-bold}",
- "render_single_language": "This ATM has speech output in {language():font-bold}"
+ "render_list_item": "This ATM has speech output in {language()}",
+ "render_single_language": "This ATM has speech output in {language()}"
}
}
}
@@ -1809,6 +1809,24 @@
"render": "Bird watching place"
}
},
+ "brothel": {
+ "description": "An establishment specifically dedicated to prostitution. ",
+ "name": "Brothels",
+ "presets": {
+ "0": {
+ "title": "a brothel"
+ }
+ },
+ "tagRenderings": {
+ "name": {
+ "question": "What is the name of this brothel?",
+ "render": "This brothel is named {name}"
+ }
+ },
+ "title": {
+ "render": "Brothel"
+ }
+ },
"cafe_pub": {
"deletion": {
"extraDeleteReasons": {
@@ -2385,6 +2403,26 @@
"render": "Charging station"
}
},
+ "cinema": {
+ "description": " A place showing movies (films), generally open to the public for a fee. Commonly referred to as a movie theater in the US",
+ "name": "Cinema",
+ "tagRenderings": {
+ "cinema_type": {
+ "mappings": {
+ "0": {
+ "then": "This is a normal cinema showing movies for all ages"
+ },
+ "1": {
+ "then": "This is an erotic cinema showing adult movies"
+ }
+ },
+ "question": "What type of cinema is this?"
+ }
+ },
+ "title": {
+ "render": "Cinema"
+ }
+ },
"climbing": {
"description": "A dummy layer which contains tagrenderings, shared among the climbing layers",
"tagRenderings": {
@@ -3859,8 +3897,8 @@
"render": {
"special": {
"question": "In which languages does this elevator have speech output?",
- "render_list_item": "This elevator has speech output in {language():font-bold}",
- "render_single_language": "This elevator has speech output in {language():font-bold}"
+ "render_list_item": "This elevator has speech output in {language()}",
+ "render_single_language": "This elevator has speech output in {language()}"
}
}
},
@@ -3891,8 +3929,8 @@
"render": {
"special": {
"question": "In which languages does this elevator have tactile writing (braille)?",
- "render_list_item": "This elevator has tactile writing in {language():font-bold}",
- "render_single_language": "This elevator has tactile writing in {language():font-bold}"
+ "render_list_item": "This elevator has tactile writing in {language()}",
+ "render_single_language": "This elevator has tactile writing in {language()}"
}
}
}
@@ -5024,6 +5062,9 @@
},
"1": {
"then": "There is no {negative-name} available at this hackerspace"
+ },
+ "2": {
+ "then": "There is a limited {negative-name} available at this hackerspace"
}
},
"question": "Is {device-name} available at this hackerspace?"
@@ -5622,6 +5663,25 @@
}
}
},
+ "love_hotel": {
+ "description": "A love hotel is a type of short-stay hotel found around the world operated primarily for the purpose of allowing guests privacy for sexual activities",
+ "name": "Love hotels",
+ "presets": {
+ "0": {
+ "description": "A love hotel is a type of short-stay hotel found around the world operated primarily for the purpose of allowing guests privacy for sexual activities.",
+ "title": "a love hotel"
+ }
+ },
+ "tagRenderings": {
+ "name": {
+ "question": "What is the name of this love hotel?",
+ "render": "This love hotel is named {name}"
+ }
+ },
+ "title": {
+ "render": "Love Hotel {name}"
+ }
+ },
"map": {
"description": "A map, meant for tourists which is permanently installed in the public space",
"name": "Maps",
@@ -7949,7 +8009,7 @@
"no_known_languages": "The main language of this school is unknown",
"question": "What is the main language of this school?
What language is spoken with the students in non-language related courses and with the administration?
",
"render_all": "The following languages are used in this school:{list()}",
- "render_single_language": "{language():font-bold} is the main language of this school"
+ "render_single_language": "{language()} is the main language of this school"
}
}
},
@@ -8620,8 +8680,8 @@
"render": {
"special": {
"question": "In which languages is there tactile writing (braille) for navigation? ",
- "render_list_item": "These stairs have tactile writing in {language():font-bold}",
- "render_single_language": "These stairs have tactile writing in {language():font-bold}"
+ "render_list_item": "These stairs have tactile writing in {language()}",
+ "render_single_language": "These stairs have tactile writing in {language()}"
}
}
}
@@ -8784,6 +8844,24 @@
"render": "Street Lamp"
}
},
+ "stripclub": {
+ "description": "A venue where erotic dance, striptease, or lap dances are performed commercially. ",
+ "name": "Stripclubs",
+ "presets": {
+ "0": {
+ "title": "a stripclub"
+ }
+ },
+ "tagRenderings": {
+ "name": {
+ "question": "What is the name of this stripclub?",
+ "render": "This stripclub is named {name}"
+ }
+ },
+ "title": {
+ "render": "Stripclub"
+ }
+ },
"surveillance_camera": {
"description": "This layer shows surveillance cameras and allows a contributor to update information and add new cameras",
"name": "Surveillance camera's",
diff --git a/langs/layers/es.json b/langs/layers/es.json
index 5d5bc8e368..a5157d619c 100644
--- a/langs/layers/es.json
+++ b/langs/layers/es.json
@@ -530,8 +530,8 @@
"render": {
"special": {
"question": "¿En qué idiomas tiene salida de voz este cajero automático?",
- "render_list_item": "Este cajero automático tiene salida de voz en {language():font-bold}",
- "render_single_language": "Este cajero automático tiene salida de voz en {language():font-bold}"
+ "render_list_item": "Este cajero automático tiene salida de voz en {language()}",
+ "render_single_language": "Este cajero automático tiene salida de voz en {language()}"
}
}
}
diff --git a/langs/layers/fr.json b/langs/layers/fr.json
index d98f26c969..5c2fc8afd3 100644
--- a/langs/layers/fr.json
+++ b/langs/layers/fr.json
@@ -5232,7 +5232,7 @@
"no_known_languages": "La langue principale de cette école est inconnue",
"question": "Quelle est la langue principale de cette école ?
Quelle langue est parlée avec les élèves des cours non linguistiques et avec l'administration ?
",
"render_all": "Ces langues sont utilisées dans cette école :{list()}",
- "render_single_language": "{language():font-bold} est la langue principale dans cette école"
+ "render_single_language": "{language()} est la langue principale dans cette école"
}
}
},
diff --git a/langs/layers/he.json b/langs/layers/he.json
index 7b9585d41d..9f06b9efab 100644
--- a/langs/layers/he.json
+++ b/langs/layers/he.json
@@ -281,8 +281,8 @@
"render": {
"special": {
"question": "באילו שפות יש לכספומט הזה פלט דיבור?",
- "render_list_item": "לכספומט הזה יש פלט דיבור ב {language():font-bold}",
- "render_single_language": "לכספומט הזה יש פלט דיבור ב {language():font-bold}"
+ "render_list_item": "לכספומט הזה יש פלט דיבור ב {language()}",
+ "render_single_language": "לכספומט הזה יש פלט דיבור ב {language()}"
}
}
}
diff --git a/langs/layers/nl.json b/langs/layers/nl.json
index dbbc87fc18..4ca5d1c69f 100644
--- a/langs/layers/nl.json
+++ b/langs/layers/nl.json
@@ -385,8 +385,8 @@
"render": {
"special": {
"question": "In welke taal is de spraak van deze geldautomaat?",
- "render_list_item": "Deze geldautomaat heeft spraak in {language():font-bold}",
- "render_single_language": "Deze automaat heeft spraak in {language():font-bold}"
+ "render_list_item": "Deze geldautomaat heeft spraak in {language()}",
+ "render_single_language": "Deze automaat heeft spraak in {language()}"
}
}
}
@@ -3684,8 +3684,8 @@
"render": {
"special": {
"question": "In welke talen heeft deze lift gesproken tekst?",
- "render_list_item": "Deze lift heeft gesproken tekst in het {language():font-bold}",
- "render_single_language": "Deze lift heeft gesproken tekst in het {language():font-bold}"
+ "render_list_item": "Deze lift heeft gesproken tekst in het {language()}",
+ "render_single_language": "Deze lift heeft gesproken tekst in het {language()}"
}
}
},
@@ -3693,8 +3693,8 @@
"render": {
"special": {
"question": "In welke talen heeft deze lift voelbaar schrift (braille)?",
- "render_list_item": "Deze lift heeft voelbaar schrift in het {language():font-bold}",
- "render_single_language": "Deze lift heeft voelbaar schrift in het {language():font-bold}"
+ "render_list_item": "Deze lift heeft voelbaar schrift in het {language()}",
+ "render_single_language": "Deze lift heeft voelbaar schrift in het {language()}"
}
}
}
@@ -4498,6 +4498,9 @@
},
"1": {
"then": "Er is geen {negative-name} beschikbaar in deze hackerspace"
+ },
+ "2": {
+ "then": "Er is een beperkte {negative-name} beschikbaar in deze hackerspace"
}
},
"question": "Is er {device-name} beschikbaar in deze hackerspace?"
@@ -7533,8 +7536,8 @@
"render": {
"special": {
"question": "In welke talen is er voelbaar schrift (braille) voor navigatie? ",
- "render_list_item": "Deze trap heeft voelbaar schrijft in {language():font-bold}",
- "render_single_language": "Deze trap heeft voelbaar schrijft in {language():font-bold}"
+ "render_list_item": "Deze trap heeft voelbaar schrijft in {language()}",
+ "render_single_language": "Deze trap heeft voelbaar schrijft in {language()}"
}
}
}
diff --git a/langs/layers/pl.json b/langs/layers/pl.json
index bc9c9bd820..7b9258b572 100644
--- a/langs/layers/pl.json
+++ b/langs/layers/pl.json
@@ -2604,7 +2604,7 @@
"render": {
"special": {
"render_all": "Następujące języki są używane w tej szkole:{list()}",
- "render_single_language": "Język {language():font-bold} jest głównym językiem używanym w tej szkole"
+ "render_single_language": "Język {language()} jest głównym językiem używanym w tej szkole"
}
}
},
diff --git a/langs/layers/pt.json b/langs/layers/pt.json
index 3e2387dc4b..ebabfd54e0 100644
--- a/langs/layers/pt.json
+++ b/langs/layers/pt.json
@@ -500,7 +500,7 @@
"render": {
"special": {
"question": "Em que línguas este multibanco tem saída de fala?",
- "render_list_item": "Este multibanco tem saída de fala em {language():font-bold}"
+ "render_list_item": "Este multibanco tem saída de fala em {language()}"
}
}
}
diff --git a/langs/layers/pt_BR.json b/langs/layers/pt_BR.json
index a472d715cf..a15bc79e7a 100644
--- a/langs/layers/pt_BR.json
+++ b/langs/layers/pt_BR.json
@@ -489,8 +489,8 @@
"render": {
"special": {
"question": "Em quais línguas esse caixa eletrônico tem saída de fala?",
- "render_list_item": "Este caixa eletrônico tem saída de fala em {language():font-bold}",
- "render_single_language": "Este caixa eletrônico tem saída de fala em {language():font-bold}"
+ "render_list_item": "Este caixa eletrônico tem saída de fala em {language()}",
+ "render_single_language": "Este caixa eletrônico tem saída de fala em {language()}"
}
}
}
diff --git a/langs/themes/ca.json b/langs/themes/ca.json
index 933eb133c3..a5cdfc921e 100644
--- a/langs/themes/ca.json
+++ b/langs/themes/ca.json
@@ -868,111 +868,6 @@
},
"title": "Vorals i encreuaments"
},
- "mapcomplete-changes": {
- "description": "Aquest mapa mostra tots els canvis fets amb MapComplete",
- "layers": {
- "0": {
- "description": "Mostra tots els canvis de MapComplete",
- "filter": {
- "0": {
- "options": {
- "0": {
- "question": "El nom del tema conté {search}"
- }
- }
- },
- "2": {
- "options": {
- "0": {
- "question": "Fet pel col·laborador {search}"
- }
- }
- },
- "3": {
- "options": {
- "0": {
- "question": "No fet pel col·laborador {search}"
- }
- }
- },
- "4": {
- "options": {
- "0": {
- "question": "Fet abans de {search}"
- }
- }
- },
- "5": {
- "options": {
- "0": {
- "question": "Fet després de {search}"
- }
- }
- },
- "6": {
- "options": {
- "0": {
- "question": "Idioma de l'usuari (codi iso) {search}"
- }
- }
- },
- "7": {
- "options": {
- "0": {
- "question": "Fet amb l'amfitrió {search}"
- }
- }
- },
- "8": {
- "options": {
- "0": {
- "question": "El conjunt de canvis ha afegit almenys una imatge"
- }
- }
- }
- },
- "tagRenderings": {
- "contributor": {
- "question": "Quin col·laborador va fer aquest canvi?",
- "render": "Canvi fet per {user}"
- },
- "host": {
- "question": "Amb quin amfitrió (lloc web) es va fer aquest canvi?",
- "render": "Canviat amb {host}"
- },
- "locale": {
- "question": "Amb quina configuració regional (idioma) s'ha fet aquest canvi?",
- "render": "La configuració regional de l'usuari és {locale}"
- },
- "show_changeset_id": {
- "render": "Conjunt de canvi {id}"
- },
- "theme-id": {
- "question": "Quin tema es va utilitzar per fer aquest canvi?",
- "render": "Canvi amb el tema {theme}"
- },
- "version": {
- "question": "Quina versió de MapComplete es va utilitzar per fer aquest canvi?",
- "render": "Fet amb {editor}"
- }
- },
- "title": {
- "render": "Conjunt de canvis per a {theme}"
- }
- },
- "1": {
- "override": {
- "tagRenderings+": {
- "0": {
- "render": "Es pot trobar més estadística aquí"
- }
- }
- }
- }
- },
- "shortDescription": "Mostra els canvis fets amb MapComplete",
- "title": "Canvis fets amb MapComplete"
- },
"maproulette": {
"description": "Tema que mostra les tasques de MapRoulette, que us permet cercar-les, filtrar-les i solucionar-les.",
"title": "Tasques de MapRoulette"
diff --git a/langs/themes/de.json b/langs/themes/de.json
index 50b41becd7..598159fdfb 100644
--- a/langs/themes/de.json
+++ b/langs/themes/de.json
@@ -898,133 +898,6 @@
},
"title": "Bordsteine und Überwege"
},
- "mapcomplete-changes": {
- "description": "Diese Karte zeigt alle mit MapComplete vorgenommenen Änderungen",
- "layers": {
- "0": {
- "description": "Zeigt alle MapComplete-Änderungen",
- "filter": {
- "0": {
- "options": {
- "0": {
- "question": "Themename enthält {search}"
- }
- }
- },
- "1": {
- "options": {
- "0": {
- "question": "Der Name enthält nicht {search}"
- }
- }
- },
- "2": {
- "options": {
- "0": {
- "question": "Der Name enthält nicht {search}"
- }
- }
- },
- "3": {
- "options": {
- "0": {
- "question": "Nicht erstellt von {search}"
- }
- }
- },
- "4": {
- "options": {
- "0": {
- "question": "Erstellt vor {search}"
- }
- }
- },
- "5": {
- "options": {
- "0": {
- "question": "Erstellt nach {search}"
- }
- }
- },
- "6": {
- "options": {
- "0": {
- "question": "Benutzersprache (ISO-Code) {search}"
- }
- }
- },
- "7": {
- "options": {
- "0": {
- "question": "Erstellt mit Host {search}"
- }
- }
- },
- "8": {
- "options": {
- "0": {
- "question": "Änderungssatz hat mindestens ein Bild hinzugefügt"
- }
- }
- },
- "9": {
- "options": {
- "0": {
- "question": "GRB-Theme ausschließen"
- }
- }
- },
- "10": {
- "options": {
- "0": {
- "question": "Etymologie-Thema ausschließen"
- }
- }
- }
- },
- "name": "Zentrum der Änderungssätze",
- "tagRenderings": {
- "contributor": {
- "question": "Wer hat diese Änderung vorgenommen?",
- "render": "Änderung von {user}"
- },
- "host": {
- "question": "Über welchen Host (Webseite) wurde diese Änderung vorgenommen?",
- "render": "Geändert über {host}"
- },
- "locale": {
- "question": "In welcher Benutzersprache wurde diese Änderung vorgenommen?",
- "render": "Benutzersprache {locale}"
- },
- "show_changeset_id": {
- "render": "Änderungssatz {id}"
- },
- "theme-id": {
- "question": "Welches Theme wurde für diese Änderung verwendet?",
- "render": "Geändert mit Thema {theme}"
- },
- "version": {
- "question": "Welche Version von MapComplete wurde verwendet, um diese Änderung vorzunehmen?",
- "render": "Erstellt mit {editor}"
- }
- },
- "title": {
- "render": "Änderungssatz für {theme}"
- }
- },
- "1": {
- "override": {
- "tagRenderings+": {
- "0": {
- "render": "Mehr Statistiken gibt es hier"
- }
- }
- }
- }
- },
- "shortDescription": "Zeigt die von MapComplete vorgenommenen Änderungen an",
- "title": "Mit MapComplete vorgenommene Änderungen"
- },
"maproulette": {
"description": "Thema mit MapRoulette-Aufgaben, die Sie suchen, filtern und beheben können.",
"title": "MapRoulette-Aufgaben"
diff --git a/langs/themes/en.json b/langs/themes/en.json
index 391755f298..934d2de157 100644
--- a/langs/themes/en.json
+++ b/langs/themes/en.json
@@ -1129,6 +1129,57 @@
},
"title": "OnWheels"
},
+ "openlovemap": {
+ "description": "
Love in the palm of your hand
Open Love Map lists various adult entries, such as brothels, erotic stores and stripclubs.",
+ "layers": {
+ "2": {
+ "override": {
+ "=presets": {
+ "0": {
+ "title": "an erotic shop"
+ }
+ },
+ "name": "Erotic shops"
+ }
+ },
+ "4": {
+ "override": {
+ "=presets": {
+ "0": {
+ "title": "a condom vending machine"
+ }
+ }
+ }
+ },
+ "6": {
+ "override": {
+ "=presets": {
+ "0": {
+ "title": "an erotic cinema"
+ }
+ }
+ }
+ },
+ "9": {
+ "override": {
+ "+tagRenderings": {
+ "0": {
+ "question": "What type of hotel is this?"
+ }
+ }
+ }
+ }
+ },
+ "overrideAll": {
+ "tagRenderings+": {
+ "0": {
+ "question": "Does {title()} have a private video booth?",
+ "questionHint": "This is for use by a single person."
+ }
+ }
+ },
+ "title": "Open Love Map"
+ },
"openwindpowermap": {
"description": "A map for showing and editing wind turbines.",
"title": "Wind power generators"
diff --git a/langs/themes/es.json b/langs/themes/es.json
index 04f00ebcda..796941f9f8 100644
--- a/langs/themes/es.json
+++ b/langs/themes/es.json
@@ -898,23 +898,6 @@
},
"title": "Bordillos y cruces"
},
- "mapcomplete-changes": {
- "description": "Este mapa muestra todos los cambios realizados con MapComplete",
- "layers": {
- "0": {
- "description": "Muestra todos los cambios de MapComplete",
- "filter": {
- "0": {
- "options": {
- "0": {
- "question": "El nombre del tema contiene {search}"
- }
- }
- }
- }
- }
- }
- },
"maproulette": {
"description": "Tema que muestra las tareas de MapRoulette, permitiendo buscarlas, filtrarlas y arreglarlas.",
"title": "Tareas de MapRoulette"
diff --git a/src/Logic/FeatureSource/Sources/OverpassFeatureSource.ts b/src/Logic/FeatureSource/Sources/OverpassFeatureSource.ts
index 51afcdfdd7..02ef73c435 100644
--- a/src/Logic/FeatureSource/Sources/OverpassFeatureSource.ts
+++ b/src/Logic/FeatureSource/Sources/OverpassFeatureSource.ts
@@ -103,7 +103,7 @@ export default class OverpassFeatureSource implements FeatureSource {
if (!result) {
return
}
- const [bounds, _, _] = result
+ const [bounds, _, __] = result
this._lastQueryBBox = bounds
}
diff --git a/src/UI/Input/README.md b/src/UI/Input/README.md
index 459e6c8565..82b6ff5477 100644
--- a/src/UI/Input/README.md
+++ b/src/UI/Input/README.md
@@ -1 +1 @@
-This is the old, deprecated directory. New, SVelte-based items go into `InputElement`
+This is the old, deprecated directory. New, Svelte-based items go into `InputElement`
diff --git a/src/UI/Input/SearchableMappingsSelector.ts b/src/UI/Input/SearchableMappingsSelector.ts
deleted file mode 100644
index 8c41b32a64..0000000000
--- a/src/UI/Input/SearchableMappingsSelector.ts
+++ /dev/null
@@ -1,304 +0,0 @@
-import { UIElement } from "../UIElement"
-import { InputElement } from "./InputElement"
-import BaseUIElement from "../BaseUIElement"
-import { Store, UIEventSource } from "../../Logic/UIEventSource"
-import Translations from "../i18n/Translations"
-import Locale from "../i18n/Locale"
-import Combine from "../Base/Combine"
-import { TextField } from "./TextField"
-import Svg from "../../Svg"
-import { VariableUiElement } from "../Base/VariableUIElement"
-
-/**
- * A single 'pill' which can hide itself if the search criteria is not met
- */
-class SelfHidingToggle extends UIElement implements InputElement {
- public readonly _selected: UIEventSource
- public readonly isShown: Store = new UIEventSource(true)
- public readonly matchesSearchCriteria: Store
- public readonly forceSelected: UIEventSource
- private readonly _shown: BaseUIElement
- private readonly _squared: boolean
-
- public constructor(
- shown: string | BaseUIElement,
- mainTerm: Record,
- search: Store,
- options?: {
- searchTerms?: Record
- selected?: UIEventSource
- forceSelected?: UIEventSource
- squared?: boolean
- /* Hide, if not selected*/
- hide?: Store
- }
- ) {
- super()
- this._shown = Translations.W(shown)
- this._squared = options?.squared ?? false
- const searchTerms: Record = {}
- for (const lng in options?.searchTerms ?? []) {
- if (lng === "_context") {
- continue
- }
- searchTerms[lng] = options?.searchTerms[lng]?.map(SelfHidingToggle.clean)
- }
- for (const lng in mainTerm) {
- if (lng === "_context") {
- continue
- }
- const main = SelfHidingToggle.clean(mainTerm[lng])
- searchTerms[lng] = [main].concat(searchTerms[lng] ?? [])
- }
- const selected = (this._selected = options?.selected ?? new UIEventSource(false))
- const forceSelected = (this.forceSelected =
- options?.forceSelected ?? new UIEventSource(false))
- this.matchesSearchCriteria = search.map((s) => {
- if (s === undefined || s.length === 0) {
- return true
- }
-
- s = s?.trim()?.toLowerCase()
- if (searchTerms[Locale.language.data]?.some((t) => t.indexOf(s) >= 0)) {
- return true
- }
- if (searchTerms["*"]?.some((t) => t.indexOf(s) >= 0)) {
- return true
- }
- return false
- })
- this.isShown = this.matchesSearchCriteria.map(
- (matchesSearch) => {
- if (selected.data && !forceSelected.data) {
- return true
- }
- if (options?.hide?.data) {
- return false
- }
- return matchesSearch
- },
- [selected, Locale.language, options?.hide]
- )
-
- const self = this
- this.isShown.addCallbackAndRun((shown) => {
- if (shown) {
- self.RemoveClass("hidden")
- } else {
- self.SetClass("hidden")
- }
- })
- }
-
- private static clean(s: string): string {
- return s?.trim()?.toLowerCase()?.replace(/[-]/, "")
- }
-
- GetValue(): UIEventSource {
- return this._selected
- }
-
- IsValid(_: boolean): boolean {
- return true
- }
-
- protected InnerRender(): string | BaseUIElement {
- let el: BaseUIElement = this._shown
- const selected = this._selected
-
- selected.addCallbackAndRun((selected) => {
- if (selected) {
- el.SetClass("border-4")
- el.RemoveClass("border")
- el.SetStyle("margin: 0")
- } else {
- el.SetStyle("margin: 3px")
- el.SetClass("border")
- el.RemoveClass("border-4")
- }
- })
-
- const forcedSelection = this.forceSelected
- el.onClick(() => {
- if (forcedSelection.data) {
- selected.setData(true)
- } else {
- selected.setData(!selected.data)
- }
- })
-
- if (!this._squared) {
- el.SetClass("rounded-full")
- }
- return el.SetClass("border border-black p-1 px-4")
- }
-}
-
-/**
- * The searchable mappings selector is a selector which shows various pills from which one (or more) options can be chosen.
- * A searchfield can be used to filter the values
- */
-export class SearchablePillsSelector extends Combine implements InputElement {
- public readonly someMatchFound: Store
- private readonly selectedElements: UIEventSource
-
- /**
- *
- * @param values: the values that can be selected
- * @param options
- */
- constructor(
- values: {
- show: BaseUIElement
- value: T
- mainTerm: Record
- searchTerms?: Record
- /* If there are more then 200 elements, should this element still be shown? */
- hasPriority?: Store
- }[],
- options?: {
- /*
- * If one single value can be selected (like a radio button) or if many values can be selected (like checkboxes)
- */
- mode?: "select-one" | "select-many"
- /**
- * The values of the selected elements.
- * Use this to tie input elements together
- */
- selectedElements?: UIEventSource
- /**
- * The search bar. Use this to seed the search value or to tie to another value
- */
- searchValue?: UIEventSource
- /**
- * What is shown if the search yielded no results.
- * By default: a translated "no search results"
- */
- onNoMatches?: BaseUIElement
- /**
- * An element that is shown if no search is entered
- * Default behaviour is to show all options
- */
- onNoSearchMade?: BaseUIElement
- /**
- * Extra element to show if there are many (>200) possible mappings and when non-priority mappings are hidden
- *
- */
- onManyElements?: BaseUIElement
- searchAreaClass?: string
- hideSearchBar?: false | boolean
- }
- ) {
- const search = new TextField({ value: options?.searchValue })
-
- const searchBar = options?.hideSearchBar
- ? undefined
- : new Combine([
- Svg.search_svg().SetClass("w-8 normal-background"),
- search.SetClass("w-full"),
- ]).SetClass("flex items-center border-2 border-black m-2")
-
- const searchValue = search.GetValue().map((s) => s?.trim()?.toLowerCase())
- const selectedElements = options?.selectedElements ?? new UIEventSource([])
- const mode = options?.mode ?? "select-one"
- const onEmpty = options?.onNoMatches ?? Translations.t.general.noMatchingMapping
- const forceHide = new UIEventSource(false)
- const mappedValues: {
- show: SelfHidingToggle
- mainTerm: Record
- value: T
- }[] = values.map((v) => {
- const vIsSelected = new UIEventSource(false)
-
- selectedElements.addCallbackAndRunD((selectedElements) => {
- vIsSelected.setData(selectedElements.some((t) => t === v.value))
- })
-
- vIsSelected.addCallback((selected) => {
- if (selected) {
- if (mode === "select-one") {
- selectedElements.setData([v.value])
- } else if (!selectedElements.data.some((t) => t === v.value)) {
- selectedElements.data.push(v.value)
- selectedElements.ping()
- }
- } else {
- for (let i = 0; i < selectedElements.data.length; i++) {
- const t = selectedElements.data[i]
- if (t == v.value) {
- selectedElements.data.splice(i, 1)
- selectedElements.ping()
- break
- }
- }
- }
- })
-
- const toggle = new SelfHidingToggle(v.show, v.mainTerm, searchValue, {
- searchTerms: v.searchTerms,
- selected: vIsSelected,
- squared: mode === "select-many",
- hide:
- v.hasPriority === undefined
- ? forceHide
- : forceHide.map((fh) => fh && !v.hasPriority?.data, [v.hasPriority]),
- })
-
- return {
- ...v,
- show: toggle,
- }
- })
-
- // The total number of elements that would be displayed based on the search criteria alone
- let totalShown: Store
- totalShown = searchValue.map(
- (_) => mappedValues.filter((mv) => mv.show.matchesSearchCriteria.data).length
- )
- const tooMuchElementsCutoff = 40
- totalShown.addCallbackAndRunD((shown) => forceHide.setData(tooMuchElementsCutoff < shown))
-
- super([
- searchBar,
- new VariableUiElement(
- Locale.language.map(
- (lng) => {
- if (
- options?.onNoSearchMade !== undefined &&
- (searchValue.data === undefined || searchValue.data.length === 0)
- ) {
- return options?.onNoSearchMade
- }
- if (totalShown.data == 0) {
- return onEmpty
- }
-
- mappedValues.sort((a, b) => (a.mainTerm[lng] < b.mainTerm[lng] ? -1 : 1))
- let pills = new Combine(mappedValues.map((e) => e.show))
- .SetClass("flex flex-wrap w-full content-start")
- .SetClass(options?.searchAreaClass ?? "")
-
- if (totalShown.data >= tooMuchElementsCutoff) {
- pills = new Combine([
- options?.onManyElements ?? Translations.t.general.useSearch,
- pills,
- ])
- }
- return pills
- },
- [totalShown, searchValue]
- )
- ),
- ])
- this.selectedElements = selectedElements
- this.someMatchFound = totalShown.map((t) => t > 0)
- }
-
- public GetValue(): UIEventSource {
- return this.selectedElements
- }
-
- IsValid(_: T[]): boolean {
- return true
- }
-}
diff --git a/src/UI/Popup/AllLanguagesSelector.ts b/src/UI/Popup/AllLanguagesSelector.ts
deleted file mode 100644
index 3d3216e670..0000000000
--- a/src/UI/Popup/AllLanguagesSelector.ts
+++ /dev/null
@@ -1,46 +0,0 @@
-import { SearchablePillsSelector } from "../Input/SearchableMappingsSelector"
-import { Store } from "../../Logic/UIEventSource"
-import BaseUIElement from "../BaseUIElement"
-import all_languages from "../../assets/language_translations.json"
-import { Translation } from "../i18n/Translation"
-
-export class AllLanguagesSelector extends SearchablePillsSelector {
- constructor(options?: {
- mode?: "select-many" | "select-one"
- currentCountry?: Store
- supportedLanguages?: Record & { _meta?: { countries?: string[] } }
- }) {
- const possibleValues: {
- show: BaseUIElement
- value: string
- mainTerm: Record
- searchTerms?: Record
- hasPriority?: Store
- }[] = []
-
- const langs = options?.supportedLanguages ?? all_languages
- for (const ln in langs) {
- let languageInfo: Record & { _meta?: { countries: string[] } } =
- all_languages[ln]
- const countries = languageInfo._meta?.countries?.map((c) => c.toLowerCase())
- languageInfo = { ...languageInfo }
- delete languageInfo._meta
- const term = {
- show: new Translation(languageInfo),
- value: ln,
- mainTerm: languageInfo,
- searchTerms: { "*": [ln] },
- hasPriority:
- countries === undefined
- ? undefined
- : options?.currentCountry?.map(
- (country) => countries?.indexOf(country.toLowerCase()) >= 0
- ),
- }
- possibleValues.push(term)
- }
- super(possibleValues, {
- mode: options?.mode ?? "select-many",
- })
- }
-}
diff --git a/src/UI/Popup/LanguageElement.ts b/src/UI/Popup/LanguageElement.ts
deleted file mode 100644
index a806faeede..0000000000
--- a/src/UI/Popup/LanguageElement.ts
+++ /dev/null
@@ -1,254 +0,0 @@
-import { SpecialVisualization, SpecialVisualizationState } from "../SpecialVisualization"
-import BaseUIElement from "../BaseUIElement"
-import { UIEventSource } from "../../Logic/UIEventSource"
-import { VariableUiElement } from "../Base/VariableUIElement"
-import all_languages from "../../assets/language_translations.json"
-import { Translation } from "../i18n/Translation"
-import Combine from "../Base/Combine"
-import Title from "../Base/Title"
-import Lazy from "../Base/Lazy"
-import { SubstitutedTranslation } from "../SubstitutedTranslation"
-import List from "../Base/List"
-import { AllLanguagesSelector } from "./AllLanguagesSelector"
-import ChangeTagAction from "../../Logic/Osm/Actions/ChangeTagAction"
-import { And } from "../../Logic/Tags/And"
-import { Tag } from "../../Logic/Tags/Tag"
-import { EditButton, SaveButton } from "./SaveButton"
-import Translations from "../i18n/Translations"
-import Toggle from "../Input/Toggle"
-import { Feature } from "geojson"
-class xyz {}
-export class LanguageElement implements SpecialVisualization {
- funcName: string = "language_chooser"
- needsUrls = []
-
- docs: string | BaseUIElement =
- "The language element allows to show and pick all known (modern) languages. The key can be set"
-
- args: { name: string; defaultValue?: string; doc: string; required?: boolean }[] = [
- {
- name: "key",
- required: true,
- doc: "What key to use, e.g. `language`, `tactile_writing:braille:language`, ... If a language is supported, the language code will be appended to this key, resulting in `language:nl=yes` if nl is picked ",
- },
- {
- name: "question",
- required: true,
- doc: "What to ask if no questions are known",
- },
- {
- name: "render_list_item",
- doc: "How a single language will be shown in the list of languages. Use `{language}` to indicate the language (which it must contain).",
- defaultValue: "{language()}",
- },
- {
- name: "render_single_language",
- doc: "What will be shown if the feature only supports a single language",
- required: true,
- },
- {
- name: "render_all",
- doc: "The full rendering. Use `{list}` to show where the list of languages must come. Optional if mode=single",
- defaultValue: "{list()}",
- },
- {
- name: "no_known_languages",
- doc: "The text that is shown if no languages are known for this key. If this text is omitted, the languages will be prompted instead",
- },
- {
- name: "mode",
- doc: "If one or many languages can be selected. Should be 'multi' or 'single'",
- defaultValue: "multi",
- },
- ]
-
- example: `
- \`\`\`json
- {"special":
- "type": "language_chooser",
- "key": "school:language",
- "question": {"en": "What are the main (and administrative) languages spoken in this school?"},
- "render_single_language": {"en": "{language()} is spoken on this school"},
- "render_list_item": {"en": "{language()}"},
- "render_all": {"en": "The following languages are spoken here:{list()}"}
- "mode":"multi"
- }
- \`\`\`
- `
-
- constr(
- state: SpecialVisualizationState,
- tagSource: UIEventSource>,
- argument: string[],
- feature: Feature
- ): BaseUIElement {
- let [key, question, item_render, single_render, all_render, on_no_known_languages, mode] =
- argument
- if (mode === undefined || mode.length == 0) {
- mode = "multi"
- }
- if (item_render === undefined || item_render.trim() === "") {
- item_render = "{language()}"
- }
- if (all_render === undefined || all_render.length == 0) {
- all_render = "{list()}"
- }
- if (mode !== "single" && mode !== "multi") {
- throw (
- "Error while calling language_chooser: mode must be either 'single' or 'multi' but it is " +
- mode
- )
- }
- if (single_render.indexOf("{language()") < 0) {
- throw (
- "Error while calling language_chooser: render_single_language must contain '{language()}' but it is " +
- single_render
- )
- }
- if (item_render.indexOf("{language()") < 0) {
- throw (
- "Error while calling language_chooser: render_list_item must contain '{language()}' but it is " +
- item_render
- )
- }
- if (all_render.indexOf("{list()") < 0) {
- throw "Error while calling language_chooser: render_all must contain '{list()}'"
- }
-
- const prefix = key + ":"
- const foundLanguages = tagSource.map((tags) => {
- const foundLanguages: string[] = []
- for (const k in tags) {
- const v = tags[k]
- if (v !== "yes") {
- continue
- }
- if (k.startsWith(prefix)) {
- foundLanguages.push(k.substring(prefix.length))
- }
- }
- return foundLanguages
- })
- const forceInputMode = new UIEventSource(false)
- const inputEl = new Lazy(() => {
- const selector = new AllLanguagesSelector({
- mode: mode === "single" ? "select-one" : "select-many",
- currentCountry: tagSource.map((tgs) => tgs["_country"]),
- })
- const cancelButton = Toggle.If(forceInputMode, () =>
- Translations.t.general.cancel
- .Clone()
- .SetClass("btn btn-secondary")
- .onClick(() => forceInputMode.setData(false))
- )
-
- const saveButton = new SaveButton(
- selector.GetValue().map((lngs) => (lngs.length > 0 ? "true" : undefined)),
- state
- ).onClick(() => {
- const selectedLanguages = selector.GetValue().data
- const currentLanguages = foundLanguages.data
- const selection: Tag[] = selectedLanguages.map((ln) => new Tag(prefix + ln, "yes"))
-
- for (const currentLanguage of currentLanguages) {
- if (selectedLanguages.indexOf(currentLanguage) >= 0) {
- continue
- }
- // Erase language that is not spoken anymore
- selection.push(new Tag(prefix + currentLanguage, ""))
- }
-
- if (state.featureSwitchIsTesting.data) {
- for (const tag of selection) {
- tagSource.data[tag.key] = tag.value
- }
- tagSource.ping()
- } else {
- ;(state?.changes)
- .applyAction(
- new ChangeTagAction(
- tagSource.data.id,
- new And(selection),
- tagSource.data,
- {
- theme: state?.layout?.id ?? "unkown",
- changeType: "answer",
- }
- )
- )
- .then((_) => {
- console.log("Tagchanges applied")
- })
- }
- forceInputMode.setData(false)
- })
-
- return new Combine([
- new Title(question),
- selector,
- new Combine([cancelButton, saveButton]).SetClass("flex justify-end"),
- ]).SetClass("flex flex-col question disable-links")
- })
-
- const editButton = new EditButton(state.osmConnection, () => forceInputMode.setData(true))
-
- return new VariableUiElement(
- foundLanguages.map(
- (foundLanguages) => {
- if (forceInputMode.data) {
- return inputEl
- }
-
- if (foundLanguages.length === 0) {
- // No languages found - we show the question and the input element
- if (
- on_no_known_languages !== undefined &&
- on_no_known_languages.length > 0
- ) {
- return new Combine([on_no_known_languages, editButton]).SetClass(
- "flex justify-end"
- )
- }
- return inputEl
- }
-
- let rendered: BaseUIElement
- if (foundLanguages.length === 1) {
- const ln = foundLanguages[0]
- let mapping = new Map()
- mapping.set("language", new Translation(all_languages[ln]))
- rendered = new SubstitutedTranslation(
- new Translation({ "*": single_render }, undefined),
- tagSource,
- state,
- mapping
- )
- } else {
- let mapping = new Map()
- const languagesList = new List(
- foundLanguages.map((ln) => {
- let mappingLn = new Map()
- mappingLn.set("language", new Translation(all_languages[ln]))
- return new SubstitutedTranslation(
- new Translation({ "*": item_render }, undefined),
- tagSource,
- state,
- mappingLn
- )
- })
- )
- mapping.set("list", languagesList)
- rendered = new SubstitutedTranslation(
- new Translation({ "*": all_render }, undefined),
- tagSource,
- state,
- mapping
- )
- }
- return new Combine([rendered, editButton]).SetClass("flex justify-between")
- },
- [forceInputMode]
- )
- )
- }
-}
diff --git a/src/UI/Popup/LanguageElement/LanguageAnswer.svelte b/src/UI/Popup/LanguageElement/LanguageAnswer.svelte
new file mode 100644
index 0000000000..3a22365d62
--- /dev/null
+++ b/src/UI/Popup/LanguageElement/LanguageAnswer.svelte
@@ -0,0 +1,46 @@
+
+
+{#if $languages.length === 1}
+
+{:else}
+ {beforeListing}
+
+{/if}
diff --git a/src/UI/Popup/LanguageElement/LanguageElement.ts b/src/UI/Popup/LanguageElement/LanguageElement.ts
new file mode 100644
index 0000000000..1f2dc8c6b5
--- /dev/null
+++ b/src/UI/Popup/LanguageElement/LanguageElement.ts
@@ -0,0 +1,107 @@
+import { SpecialVisualization, SpecialVisualizationState } from "../../SpecialVisualization"
+import BaseUIElement from "../../BaseUIElement"
+import { UIEventSource } from "../../../Logic/UIEventSource"
+import SvelteUIElement from "../../Base/SvelteUIElement"
+import { Feature } from "geojson"
+import LayerConfig from "../../../Models/ThemeConfig/LayerConfig"
+import { default as LanguageElementSvelte } from "./LanguageElement.svelte"
+
+export class LanguageElement implements SpecialVisualization {
+ funcName: string = "language_chooser"
+ needsUrls = []
+
+ docs: string | BaseUIElement =
+ "The language element allows to show and pick all known (modern) languages. The key can be set"
+
+ args: { name: string; defaultValue?: string; doc: string; required?: boolean }[] = [
+ {
+ name: "key",
+ required: true,
+ doc: "What key to use, e.g. `language`, `tactile_writing:braille:language`, ... If a language is supported, the language code will be appended to this key, resulting in `language:nl=yes` if nl is picked ",
+ },
+ {
+ name: "question",
+ required: true,
+ doc: "What to ask if no questions are known",
+ },
+ {
+ name: "render_list_item",
+ doc: "How a single language will be shown in the list of languages. Use `{language}` to indicate the language (which it must contain).",
+ defaultValue: "{language()}",
+ },
+ {
+ name: "render_single_language",
+ doc: "What will be shown if the feature only supports a single language",
+ required: true,
+ },
+ {
+ name: "render_all",
+ doc: "The full rendering. Use `{list}` to show where the list of languages must come. Optional if mode=single",
+ defaultValue: "{list()}",
+ },
+ {
+ name: "no_known_languages",
+ doc: "The text that is shown if no languages are known for this key. If this text is omitted, the languages will be prompted instead",
+ },
+ ]
+
+ example: `
+ \`\`\`json
+ {"special":
+ "type": "language_chooser",
+ "key": "school:language",
+ "question": {"en": "What are the main (and administrative) languages spoken in this school?"},
+ "render_single_language": {"en": "{language()} is spoken on this school"},
+ "render_list_item": {"en": "{language()}"},
+ "render_all": {"en": "The following languages are spoken here:{list()}"}
+ }
+ \`\`\`
+ `
+
+ constr(
+ state: SpecialVisualizationState,
+ tagSource: UIEventSource>,
+ argument: string[],
+ feature: Feature,
+ layer: LayerConfig
+ ): BaseUIElement {
+ let [key, question, item_render, single_render, all_render, on_no_known_languages] =
+ argument
+ if (item_render === undefined || item_render.trim() === "") {
+ item_render = "{language()}"
+ }
+ if (all_render === undefined || all_render.length == 0) {
+ all_render = "{list()}"
+ }
+ if (single_render.indexOf("{language()") < 0) {
+ throw (
+ "Error while calling language_chooser: render_single_language must contain '{language()}' but it is " +
+ single_render
+ )
+ }
+ if (item_render.indexOf("{language()") < 0) {
+ throw (
+ "Error while calling language_chooser: render_list_item must contain '{language()}' but it is " +
+ item_render
+ )
+ }
+ if (all_render.indexOf("{list()") < 0) {
+ throw "Error while calling language_chooser: render_all must contain '{list()}'"
+ }
+ if (on_no_known_languages === "") {
+ on_no_known_languages = undefined
+ }
+
+ return new SvelteUIElement(LanguageElementSvelte, {
+ key,
+ tags: tagSource,
+ state,
+ feature,
+ layer,
+ question,
+ on_no_known_languages,
+ single_render,
+ item_render,
+ })
+ }
+}
diff --git a/src/UI/Popup/LanguageElement/LanguageOptions.svelte b/src/UI/Popup/LanguageElement/LanguageOptions.svelte
new file mode 100644
index 0000000000..62f78b776f
--- /dev/null
+++ b/src/UI/Popup/LanguageElement/LanguageOptions.svelte
@@ -0,0 +1,133 @@
+
+
diff --git a/src/UI/Popup/LanguageElement/LanguageQuestion.svelte b/src/UI/Popup/LanguageElement/LanguageQuestion.svelte
new file mode 100644
index 0000000000..5cd892ff73
--- /dev/null
+++ b/src/UI/Popup/LanguageElement/LanguageQuestion.svelte
@@ -0,0 +1,87 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/UI/Popup/SaveButton.ts b/src/UI/Popup/SaveButton.ts
deleted file mode 100644
index 26a36ca896..0000000000
--- a/src/UI/Popup/SaveButton.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import { Store } from "../../Logic/UIEventSource"
-import Translations from "../i18n/Translations"
-import { OsmConnection } from "../../Logic/Osm/OsmConnection"
-import Toggle from "../Input/Toggle"
-import BaseUIElement from "../BaseUIElement"
-import Combine from "../Base/Combine"
-import Svg from "../../Svg"
-import { LoginToggle } from "./LoginButton"
-
-export class EditButton extends Toggle {
- constructor(osmConnection: OsmConnection, onClick: () => void) {
- super(
- new Combine([Svg.pencil_svg()])
- .SetClass("block relative h-10 w-10 p-2 float-right")
- .SetStyle("border: 1px solid black; border-radius: 0.7em")
- .onClick(onClick),
- undefined,
- osmConnection.isLoggedIn
- )
- }
-}
-
-export class SaveButton extends LoginToggle {
- constructor(
- value: Store,
- state: {
- readonly osmConnection?: OsmConnection
- readonly featureSwitchUserbadge?: Store
- },
- textEnabled?: BaseUIElement,
- textDisabled?: BaseUIElement
- ) {
- if (value === undefined) {
- throw "No event source for savebutton, something is wrong"
- }
-
- const isSaveable = value.map((v) => v !== false && (v ?? "") !== "")
-
- const saveEnabled = (textEnabled ?? Translations.t.general.save.Clone()).SetClass(`btn`)
- const saveDisabled = (textDisabled ?? Translations.t.general.save.Clone()).SetClass(
- `btn btn-disabled`
- )
-
- const save = new Toggle(saveEnabled, saveDisabled, isSaveable)
- super(save, Translations.t.general.loginToStart, state)
- }
-}
diff --git a/src/UI/Popup/TagRendering/EditButton.svelte b/src/UI/Popup/TagRendering/EditButton.svelte
new file mode 100644
index 0000000000..031680583c
--- /dev/null
+++ b/src/UI/Popup/TagRendering/EditButton.svelte
@@ -0,0 +1,23 @@
+
+
+
diff --git a/src/UI/Popup/TagRendering/TagRenderingEditable.svelte b/src/UI/Popup/TagRendering/TagRenderingEditable.svelte
index bf233b0e66..c2312021c9 100644
--- a/src/UI/Popup/TagRendering/TagRenderingEditable.svelte
+++ b/src/UI/Popup/TagRendering/TagRenderingEditable.svelte
@@ -13,6 +13,8 @@
import { Utils } from "../../../Utils"
import { twMerge } from "tailwind-merge"
import { ariaLabel } from "../../../Utils/ariaLabel"
+ import EditButton from "./EditButton.svelte"
+ import EditItemButton from "../../Studio/EditItemButton.svelte"
export let config: TagRenderingConfig
export let tags: UIEventSource>
@@ -102,16 +104,12 @@
{:else}
-
+ editMode = true
+ }}/>
{/if}
{:else}
diff --git a/src/UI/SpecialVisualizations.ts b/src/UI/SpecialVisualizations.ts
index 9145ef99a6..c94a1a3ce2 100644
--- a/src/UI/SpecialVisualizations.ts
+++ b/src/UI/SpecialVisualizations.ts
@@ -31,11 +31,10 @@ import OpeningHoursVisualization from "./OpeningHours/OpeningHoursVisualization"
import { SubtleButton } from "./Base/SubtleButton"
import Svg from "../Svg"
import NoteCommentElement from "./Popup/Notes/NoteCommentElement"
-import { SubstitutedTranslation } from "./SubstitutedTranslation"
import List from "./Base/List"
import StatisticsPanel from "./BigComponents/StatisticsPanel"
import AutoApplyButton from "./Popup/AutoApplyButton"
-import { LanguageElement } from "./Popup/LanguageElement"
+import { LanguageElement } from "./Popup/LanguageElement/LanguageElement"
import FeatureReviews from "../Logic/Web/MangroveReviews"
import Maproulette from "../Logic/Maproulette"
import SvelteUIElement from "./Base/SvelteUIElement"
@@ -88,6 +87,7 @@ import MaprouletteSetStatus from "./MapRoulette/MaprouletteSetStatus.svelte"
import DirectionIndicator from "./Base/DirectionIndicator.svelte"
import Img from "./Base/Img"
import Qr from "../Utils/Qr"
+import SpecialTranslation from "./Popup/TagRendering/SpecialTranslation.svelte"
class NearbyImageVis implements SpecialVisualization {
// Class must be in SpecialVisualisations due to weird cyclical import that breaks the tests
@@ -1044,20 +1044,28 @@ export default class SpecialVisualizations {
docs: "Shows the title of the popup. Useful for some cases, e.g. 'What is phone number of {title()}?'",
example:
"`What is the phone number of {title()}`, which might automatically become `What is the phone number of XYZ`.",
- constr: (state, tagsSource) =>
+ constr: (
+ state: SpecialVisualizationState,
+ tagsSource: UIEventSource>,
+ _: string[],
+ feature: Feature,
+ layer: LayerConfig
+ ) =>
new VariableUiElement(
tagsSource.map((tags) => {
if (state.layout === undefined) {
return ""
}
- const layer = state.layout?.getMatchingLayer(tags)
const title = layer?.title?.GetRenderValue(tags)
if (title === undefined) {
return undefined
}
- return new SubstitutedTranslation(title, tagsSource, state).SetClass(
- "px-1"
- )
+ return new SvelteUIElement(SpecialTranslation, {
+ tags: tagsSource,
+ state,
+ feature,
+ layer,
+ }).SetClass("px-1")
})
),
},
@@ -1311,7 +1319,13 @@ export default class SpecialVisualizations {
required: true,
},
],
- constr(state, featureTags, args) {
+ constr(
+ state: SpecialVisualizationState,
+ featureTags: UIEventSource>,
+ args: string[],
+ feature: Feature,
+ layer: LayerConfig
+ ) {
const [key, tr] = args
const translation = new Translation({ "*": tr })
return new VariableUiElement(
@@ -1319,11 +1333,13 @@ export default class SpecialVisualizations {
const properties: object[] = JSON.parse(tags[key])
const elements = []
for (const property of properties) {
- const subsTr = new SubstitutedTranslation(
- translation,
- new UIEventSource(property),
- state
- )
+ const subsTr = new SvelteUIElement(SpecialTranslation, {
+ t: translation,
+ tags: properties,
+ state,
+ feature,
+ layer,
+ })
elements.push(subsTr)
}
return new List(elements)
diff --git a/src/UI/SubstitutedTranslation.ts b/src/UI/SubstitutedTranslation.ts
deleted file mode 100644
index 05325e4023..0000000000
--- a/src/UI/SubstitutedTranslation.ts
+++ /dev/null
@@ -1,118 +0,0 @@
-import { UIEventSource } from "../Logic/UIEventSource"
-import { Translation } from "./i18n/Translation"
-import Locale from "./i18n/Locale"
-import { FixedUiElement } from "./Base/FixedUiElement"
-import { Utils } from "../Utils"
-import { VariableUiElement } from "./Base/VariableUIElement"
-import Combine from "./Base/Combine"
-import BaseUIElement from "./BaseUIElement"
-import LinkToWeblate from "./Base/LinkToWeblate"
-import { SpecialVisualization, SpecialVisualizationState } from "./SpecialVisualization"
-import SpecialVisualizations from "./SpecialVisualizations"
-import { Feature } from "geojson"
-import LayerConfig from "../Models/ThemeConfig/LayerConfig"
-
-/**
- * @deprecated - use 'SpecialTranslation' instead
- */
-export class SubstitutedTranslation extends VariableUiElement {
- public constructor(
- translation: Translation,
- tagsSource: UIEventSource>,
- state: SpecialVisualizationState,
- mapping: Map<
- string,
- | BaseUIElement
- | ((
- state: SpecialVisualizationState,
- tagSource: UIEventSource>,
- argument: string[],
- feature: Feature,
- layer: LayerConfig
- ) => BaseUIElement)
- > = undefined
- ) {
- const extraMappings: SpecialVisualization[] = []
-
- mapping?.forEach((value, key) => {
- extraMappings.push({
- funcName: key,
- constr: typeof value === "function" ? value : () => value,
- docs: "Dynamically injected input element",
- args: [],
- needsUrls: [],
- example: "",
- })
- })
-
- const linkToWeblate =
- translation !== undefined
- ? new LinkToWeblate(translation.context, translation.translations)
- : undefined
-
- super(
- Locale.language.map((language) => {
- let txt = translation?.textFor(language)
- if (txt === undefined) {
- return undefined
- }
- mapping?.forEach((_, key) => {
- txt = txt.replace(new RegExp(`{${key}}`, "g"), `{${key}()}`)
- })
-
- const allElements = SpecialVisualizations.constructSpecification(
- txt,
- extraMappings
- ).map((proto) => {
- if (typeof proto === "string") {
- if (tagsSource === undefined) {
- return Utils.SubstituteKeys(proto, undefined)
- }
- return new VariableUiElement(
- tagsSource.map((tags) => Utils.SubstituteKeys(proto, tags))
- )
- }
- const viz: {
- func: SpecialVisualization
- args: string[]
- style: string
- } = proto
- if (viz === undefined) {
- console.error(
- "SPECIALRENDERING UNDEFINED for",
- tagsSource.data?.id,
- "THIS IS REALLY WEIRD"
- )
- return undefined
- }
- try {
- const feature = state.indexedFeatures.featuresById.data.get(
- tagsSource.data.id
- )
- return viz.func
- .constr(
- state,
- tagsSource,
- proto.args.map((t) => SpecialVisualizations.undoEncoding(t)),
- feature,
- undefined
- )
- ?.SetStyle(proto.style)
- } catch (e) {
- console.error("SPECIALRENDERING FAILED for", tagsSource.data?.id, e)
- return new FixedUiElement(
- `Could not generate special rendering for ${
- viz.func.funcName
- }(${viz.args.join(", ")}) ${e}`
- ).SetStyle("alert")
- }
- })
- allElements.push(linkToWeblate)
-
- return new Combine(allElements)
- })
- )
-
- this.SetClass("w-full")
- }
-}
diff --git a/src/UI/Test.svelte b/src/UI/Test.svelte
index c4d5d18230..29acbc7d67 100644
--- a/src/UI/Test.svelte
+++ b/src/UI/Test.svelte
@@ -1,7 +1,16 @@
-
+
+
diff --git a/src/UI/i18n/Translation.ts b/src/UI/i18n/Translation.ts
index 806ce0ceea..96145adb57 100644
--- a/src/UI/i18n/Translation.ts
+++ b/src/UI/i18n/Translation.ts
@@ -9,8 +9,6 @@ export class Translation extends BaseUIElement {
public readonly translations: Record
public readonly context?: string
-
- private _current: Store
private onDestroy: () => void
constructor(translations: string | Record, context?: string) {
@@ -43,9 +41,11 @@ export class Translation extends BaseUIElement {
console.error(
"Non-string object at",
context,
+ "of type",
+ typeof translations[translationsKey],
`for language`,
translationsKey,
- `in translation: `,
+ `. The offending object is: `,
translations[translationsKey],
"\n current translations are: ",
translations
@@ -66,9 +66,7 @@ export class Translation extends BaseUIElement {
}
}
- get txt(): string {
- return this.textFor(Translation.forcedLanguage ?? Locale.language.data)
- }
+ private _current: Store
get current(): Store {
if (!this._current) {
@@ -82,6 +80,11 @@ export class Translation extends BaseUIElement {
}
return this._current
}
+
+ get txt(): string {
+ return this.textFor(Translation.forcedLanguage ?? Locale.language.data)
+ }
+
static ExtractAllTranslationsFrom(
object: any,
context = ""
@@ -368,4 +371,32 @@ export class TypedTranslation> extends Translation
return new TypedTranslation>(newTranslations, this.context)
}
+
+ PartialSubsTr(
+ key: string,
+ replaceWith: Translation
+ ): TypedTranslation> {
+ const newTranslations: Record = {}
+ const toSearch = "{" + key + "}"
+ const missingLanguages = new Set(Object.keys(this.translations))
+ for (const lang in this.translations) {
+ missingLanguages.delete(lang)
+ const template = this.translations[lang]
+ if (lang === "_context") {
+ newTranslations[lang] = template
+ continue
+ }
+ const v = replaceWith.textFor(lang)
+ newTranslations[lang] = template.replaceAll(toSearch, v)
+ }
+ const baseTemplate = this.textFor("en")
+ for (const missingLanguage of missingLanguages) {
+ newTranslations[missingLanguage] = baseTemplate.replaceAll(
+ toSearch,
+ replaceWith.textFor(missingLanguage)
+ )
+ }
+
+ return new TypedTranslation>(newTranslations, this.context)
+ }
}