forked from MapComplete/MapComplete
Add layer translation files
This commit is contained in:
parent
caba824a54
commit
d2d0209ead
9 changed files with 6060 additions and 227 deletions
57
langs/layers/ca.json
Normal file
57
langs/layers/ca.json
Normal file
|
@ -0,0 +1,57 @@
|
|||
{
|
||||
"defibrillator": {
|
||||
"name": "Desfibril·ladors",
|
||||
"title": {
|
||||
"render": "Desfibril·lador"
|
||||
},
|
||||
"presets": {
|
||||
"0": {
|
||||
"title": "Desfibril·lador"
|
||||
}
|
||||
},
|
||||
"tagRenderings": {
|
||||
"1": {
|
||||
"question": "Està el desfibril·lador a l'interior?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Aquest desfibril·lador està a l'interior"
|
||||
},
|
||||
"1": {
|
||||
"then": "Aquest desfibril·lador està a l'exterior"
|
||||
}
|
||||
}
|
||||
},
|
||||
"2": {
|
||||
"question": "Està el desfibril·lador accessible lliurement?",
|
||||
"render": "L'accés és {access}",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Accés lliure"
|
||||
},
|
||||
"1": {
|
||||
"then": "Publicament accessible"
|
||||
},
|
||||
"2": {
|
||||
"then": "Només accessible a clients"
|
||||
},
|
||||
"3": {
|
||||
"then": "No accessible al públic en general (ex. només accesible a treballadors, propietaris, ...)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"4": {
|
||||
"question": "A quina planta està el desfibril·lador localitzat?",
|
||||
"render": "Aquest desfibril·lador és a la planta {level}"
|
||||
},
|
||||
"5": {
|
||||
"question": "Dóna detalls d'on es pot trobar el desfibril·lador"
|
||||
},
|
||||
"6": {
|
||||
"question": "Dóna detalls d'on es pot trobar el desfibril·lador"
|
||||
},
|
||||
"7": {
|
||||
"question": "Dóna detalls d'on es pot trobar el desfibril·lador"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
824
langs/layers/de.json
Normal file
824
langs/layers/de.json
Normal file
|
@ -0,0 +1,824 @@
|
|||
{
|
||||
"bench": {
|
||||
"name": "Sitzbänke",
|
||||
"title": {
|
||||
"render": "Sitzbank"
|
||||
},
|
||||
"tagRenderings": {
|
||||
"1": {
|
||||
"render": "Rückenlehne",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Rückenlehne: Ja"
|
||||
},
|
||||
"1": {
|
||||
"then": "Rückenlehne: Nein"
|
||||
}
|
||||
},
|
||||
"question": "Hat diese Bank eine Rückenlehne?"
|
||||
},
|
||||
"2": {
|
||||
"render": "{seats} Sitzplätze",
|
||||
"question": "Wie viele Sitzplätze hat diese Bank?"
|
||||
},
|
||||
"3": {
|
||||
"render": "Material: {material}",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Material: Holz"
|
||||
},
|
||||
"1": {
|
||||
"then": "Material: Metall"
|
||||
},
|
||||
"2": {
|
||||
"then": "Material: Stein"
|
||||
},
|
||||
"3": {
|
||||
"then": "Material: Beton"
|
||||
},
|
||||
"4": {
|
||||
"then": "Material: Kunststoff"
|
||||
},
|
||||
"5": {
|
||||
"then": "Material: Stahl"
|
||||
}
|
||||
},
|
||||
"question": "Aus welchem Material besteht die Sitzbank (Sitzfläche)?"
|
||||
},
|
||||
"4": {
|
||||
"question": "In welche Richtung schaut man, wenn man auf der Bank sitzt?",
|
||||
"render": "Wenn man auf der Bank sitzt, schaut man in Richtung {direction}°."
|
||||
},
|
||||
"5": {
|
||||
"render": "Farbe: {colour}",
|
||||
"question": "Welche Farbe hat diese Sitzbank?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Farbe: braun"
|
||||
},
|
||||
"1": {
|
||||
"then": "Farbe: grün"
|
||||
},
|
||||
"2": {
|
||||
"then": "Farbe: grau"
|
||||
},
|
||||
"3": {
|
||||
"then": "Farbe: weiß"
|
||||
},
|
||||
"4": {
|
||||
"then": "Farbe: rot"
|
||||
},
|
||||
"5": {
|
||||
"then": "Farbe: schwarz"
|
||||
},
|
||||
"6": {
|
||||
"then": "Farbe: blau"
|
||||
},
|
||||
"7": {
|
||||
"then": "Farbe: gelb"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"presets": {
|
||||
"0": {
|
||||
"title": "Sitzbank",
|
||||
"description": "Neue Sitzbank eintragen"
|
||||
}
|
||||
}
|
||||
},
|
||||
"bench_at_pt": {
|
||||
"name": "Sitzbänke bei Haltestellen",
|
||||
"title": {
|
||||
"render": "Sitzbank",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Sitzbank bei Haltestelle"
|
||||
},
|
||||
"1": {
|
||||
"then": "Sitzbank in Unterstand"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tagRenderings": {
|
||||
"1": {
|
||||
"render": "{name}"
|
||||
},
|
||||
"2": {
|
||||
"render": "Stehbank"
|
||||
}
|
||||
}
|
||||
},
|
||||
"bike_cafe": {
|
||||
"name": "Fahrrad-Café",
|
||||
"title": {
|
||||
"render": "Fahrrad-Café",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Fahrrad-Café <i>{name}</i>"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tagRenderings": {
|
||||
"1": {
|
||||
"question": "Wie heißt dieses Fahrrad-Café?",
|
||||
"render": "Dieses Fahrrad-Café heißt {name}"
|
||||
},
|
||||
"2": {
|
||||
"question": "Bietet dieses Fahrrad-Café eine Fahrradpumpe an, die von jedem benutzt werden kann?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Dieses Fahrrad-Café bietet eine Fahrradpumpe an, die von jedem benutzt werden kann"
|
||||
},
|
||||
"1": {
|
||||
"then": "Dieses Fahrrad-Café bietet keine Fahrradpumpe an, die von jedem benutzt werden kann"
|
||||
}
|
||||
}
|
||||
},
|
||||
"3": {
|
||||
"question": "Gibt es hier Werkzeuge, um das eigene Fahrrad zu reparieren?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Dieses Fahrrad-Café bietet Werkzeuge für die selbständige Reparatur an."
|
||||
},
|
||||
"1": {
|
||||
"then": "Dieses Fahrrad-Café bietet keine Werkzeuge für die selbständige Reparatur an."
|
||||
}
|
||||
}
|
||||
},
|
||||
"4": {
|
||||
"question": "Repariert dieses Fahrrad-Café Fahrräder?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Dieses Fahrrad-Café repariert Fahrräder"
|
||||
},
|
||||
"1": {
|
||||
"then": "Dieses Fahrrad-Café repariert keine Fahrräder"
|
||||
}
|
||||
}
|
||||
},
|
||||
"5": {
|
||||
"question": "Was ist die Webseite von {name}?"
|
||||
},
|
||||
"6": {
|
||||
"question": "Wie lautet die Telefonnummer von {name}?"
|
||||
},
|
||||
"7": {
|
||||
"question": "Wie lautet die E-Mail-Adresse von {name}?"
|
||||
}
|
||||
},
|
||||
"presets": {
|
||||
"0": {
|
||||
"title": "Fahrrad-Café"
|
||||
}
|
||||
}
|
||||
},
|
||||
"bike_parking": {
|
||||
"name": "Fahrrad-Parkplätze",
|
||||
"presets": {
|
||||
"0": {
|
||||
"title": "Fahrrad-Parkplätze"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"render": "Fahrrad-Parkplätze"
|
||||
},
|
||||
"tagRenderings": {
|
||||
"1": {
|
||||
"question": "Was ist die Art dieses Fahrrad-Parkplatzes?",
|
||||
"render": "Dies ist ein Fahrrad-Parkplatz der Art: {bicycle_parking}",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Fahrradbügel <img style='width: 25%'' src='./assets/layers/bike_parking/staple.svg'>"
|
||||
},
|
||||
"1": {
|
||||
"then": "Metallgestänge <img style='width: 25%'' src='./assets/layers/bike_parking/wall_loops.svg'>"
|
||||
},
|
||||
"2": {
|
||||
"then": "Halter für Fahrradlenker <img style='width: 25%'' src='./assets/layers/bike_parking/handlebar_holder.svg'>"
|
||||
},
|
||||
"3": {
|
||||
"then": "Gestell <img style='width: 25%'' src='./assets/layers/bike_parking/rack.svg'>"
|
||||
},
|
||||
"4": {
|
||||
"then": "Zweistufig <img style='width: 25%'' src='./assets/layers/bike_parking/two_tier.svg'>"
|
||||
},
|
||||
"5": {
|
||||
"then": "Schuppen <img style='width: 25%'' src='./assets/layers/bike_parking/shed.svg'>"
|
||||
}
|
||||
}
|
||||
},
|
||||
"3": {
|
||||
"question": "Ist dieser Parkplatz überdacht? Wählen Sie auch \"überdacht\" für Innenparkplätze.",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Dieser Parkplatz ist überdacht (er hat ein Dach)"
|
||||
},
|
||||
"1": {
|
||||
"then": "Dieser Parkplatz ist nicht überdacht."
|
||||
}
|
||||
}
|
||||
},
|
||||
"4": {
|
||||
"question": "Wie viele Fahrräder passen auf diesen Fahrrad-Parkplatz (einschließlich möglicher Lastenfahrräder)?",
|
||||
"render": "Platz für {capacity} Fahrräder"
|
||||
},
|
||||
"6": {
|
||||
"question": "Gibt es auf diesem Fahrrad-Parkplatz Plätze für Lastenfahrräder?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Dieser Parkplatz bietet Platz für Lastenfahrräder"
|
||||
},
|
||||
"1": {
|
||||
"then": "Dieser Parkplatz verfügt über ausgewiesene (offizielle) Plätze für Lastenfahrräder."
|
||||
},
|
||||
"2": {
|
||||
"then": "Es ist nicht erlaubt, Lastenfahrräder zu parken"
|
||||
}
|
||||
}
|
||||
},
|
||||
"7": {
|
||||
"question": "Wie viele Lastenfahrräder passen auf diesen Fahrrad-Parkplatz?",
|
||||
"render": "Auf diesen Parkplatz passen {capacity:cargo_bike} Lastenfahrräder"
|
||||
}
|
||||
}
|
||||
},
|
||||
"bike_repair_station": {
|
||||
"name": "Fahrradstationen (Reparatur, Pumpe oder beides)",
|
||||
"title": {
|
||||
"render": "Fahrradstation (Pumpe & Reparatur)",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Fahrrad-Reparaturstation"
|
||||
},
|
||||
"1": {
|
||||
"then": "Fahrrad-Reparaturstation"
|
||||
},
|
||||
"2": {
|
||||
"then": "Kaputte Pumpe"
|
||||
},
|
||||
"3": {
|
||||
"then": "Fahrradpumpe <i>{name}</i>"
|
||||
},
|
||||
"4": {
|
||||
"then": "Fahrradpumpe"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tagRenderings": {
|
||||
"1": {
|
||||
"question": "Welche Einrichtungen stehen an dieser Fahrradstation zur Verfügung?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Es ist nur eine Pumpe vorhanden"
|
||||
},
|
||||
"1": {
|
||||
"then": "Es sind nur Werkzeuge (Schraubenzieher, Zangen...) vorhanden"
|
||||
},
|
||||
"2": {
|
||||
"then": "Es sind sowohl Werkzeuge als auch eine Pumpe vorhanden"
|
||||
}
|
||||
}
|
||||
},
|
||||
"4": {
|
||||
"question": "Verfügt diese Fahrrad-Reparaturstation über Spezialwerkzeug zur Reparatur von Fahrradketten?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Es gibt ein Kettenwerkzeug"
|
||||
},
|
||||
"1": {
|
||||
"then": "Es gibt kein Kettenwerkzeug"
|
||||
}
|
||||
}
|
||||
},
|
||||
"5": {
|
||||
"question": "Hat diese Fahrradstation einen Haken, an dem Sie Ihr Fahrrad aufhängen können, oder einen Ständer, um es anzuheben?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Es gibt einen Haken oder Ständer"
|
||||
},
|
||||
"1": {
|
||||
"then": "Es gibt keinen Haken oder Ständer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"6": {
|
||||
"question": "Ist die Fahrradpumpe noch funktionstüchtig?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Die Fahrradpumpe ist kaputt"
|
||||
},
|
||||
"1": {
|
||||
"then": "Die Fahrradpumpe ist betriebsbereit"
|
||||
}
|
||||
}
|
||||
},
|
||||
"7": {
|
||||
"question": "Welche Ventile werden unterstützt?",
|
||||
"render": "Diese Pumpe unterstützt die folgenden Ventile: {valves}",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Sklaverand (auch bekannt als Presta)"
|
||||
},
|
||||
"1": {
|
||||
"then": "Dunlop"
|
||||
},
|
||||
"2": {
|
||||
"then": "Schrader (Autos)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"8": {
|
||||
"question": "Ist dies eine elektrische Fahrradpumpe?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Manuelle Pumpe"
|
||||
},
|
||||
"1": {
|
||||
"then": "Elektrische Pumpe"
|
||||
}
|
||||
}
|
||||
},
|
||||
"9": {
|
||||
"question": "Verfügt die Pumpe über einen Druckanzeiger oder ein Manometer?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Es gibt ein Manometer"
|
||||
},
|
||||
"1": {
|
||||
"then": "Es gibt kein Manometer"
|
||||
},
|
||||
"2": {
|
||||
"then": "Es gibt ein Manometer, aber es ist kaputt"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"presets": {
|
||||
"0": {
|
||||
"title": "Fahrradpumpe"
|
||||
},
|
||||
"1": {
|
||||
"title": "Fahrrad-Reparaturstation und Pumpe"
|
||||
},
|
||||
"2": {
|
||||
"title": "Fahrrad-Reparaturstation ohne Pumpe"
|
||||
}
|
||||
}
|
||||
},
|
||||
"bike_shop": {
|
||||
"name": "Fahrradwerkstatt/geschäft",
|
||||
"title": {
|
||||
"render": "Fahrradwerkstatt/geschäft",
|
||||
"mappings": {
|
||||
"3": {
|
||||
"then": "Fahrradwerkstatt <i>{name}</i>"
|
||||
},
|
||||
"4": {
|
||||
"then": "Fahrradgeschäft <i>{name}</i>"
|
||||
},
|
||||
"5": {
|
||||
"then": "Fahrradwerkstatt/geschäft <i>{name}</i>"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tagRenderings": {
|
||||
"2": {
|
||||
"question": "Wie heißt dieser Fahrradladen?",
|
||||
"render": "Dieses Fahrradgeschäft heißt {name}"
|
||||
},
|
||||
"9": {
|
||||
"question": "Verkauft dieser Laden Fahrräder?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Dieses Geschäft verkauft Fahrräder"
|
||||
},
|
||||
"1": {
|
||||
"then": "Dieses Geschäft verkauft keine Fahrräder"
|
||||
}
|
||||
}
|
||||
},
|
||||
"10": {
|
||||
"question": "Repariert dieses Geschäft Fahrräder?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Dieses Geschäft repariert Fahrräder"
|
||||
},
|
||||
"1": {
|
||||
"then": "Dieses Geschäft repariert keine Fahrräder"
|
||||
},
|
||||
"2": {
|
||||
"then": "Dieses Geschäft repariert nur hier gekaufte Fahrräder"
|
||||
},
|
||||
"3": {
|
||||
"then": "Dieses Geschäft repariert nur Fahrräder einer bestimmten Marke"
|
||||
}
|
||||
}
|
||||
},
|
||||
"11": {
|
||||
"question": "Vermietet dieser Laden Fahrräder?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Dieses Geschäft vermietet Fahrräder"
|
||||
},
|
||||
"1": {
|
||||
"then": "Dieses Geschäft vermietet keine Fahrräder"
|
||||
}
|
||||
}
|
||||
},
|
||||
"12": {
|
||||
"question": "Verkauft dieses Geschäft gebrauchte Fahrräder?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Dieses Geschäft verkauft gebrauchte Fahrräder"
|
||||
},
|
||||
"1": {
|
||||
"then": "Dieses Geschäft verkauft keine gebrauchten Fahrräder"
|
||||
},
|
||||
"2": {
|
||||
"then": "Dieses Geschäft verkauft nur gebrauchte Fahrräder"
|
||||
}
|
||||
}
|
||||
},
|
||||
"13": {
|
||||
"question": "Bietet dieses Geschäft eine Fahrradpumpe zur Benutzung für alle an?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Dieses Geschäft bietet eine Fahrradpumpe für alle an"
|
||||
},
|
||||
"1": {
|
||||
"then": "Dieses Geschäft bietet für niemanden eine Fahrradpumpe an"
|
||||
}
|
||||
}
|
||||
},
|
||||
"14": {
|
||||
"question": "Gibt es hier Werkzeuge, um das eigene Fahrrad zu reparieren?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Dieses Geschäft bietet Werkzeuge für die Heimwerkerreparatur an"
|
||||
},
|
||||
"1": {
|
||||
"then": "Dieses Geschäft bietet keine Werkzeuge für Heimwerkerreparaturen an"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"presets": {
|
||||
"0": {
|
||||
"title": "Fahrradwerkstatt/geschäft"
|
||||
}
|
||||
}
|
||||
},
|
||||
"bike_themed_object": {
|
||||
"name": "Mit Fahrrad zusammenhängendes Objekt",
|
||||
"title": {
|
||||
"render": "Mit Fahrrad zusammenhängendes Objekt"
|
||||
}
|
||||
},
|
||||
"defibrillator": {
|
||||
"name": "Defibrillatoren",
|
||||
"title": {
|
||||
"render": "Defibrillator"
|
||||
},
|
||||
"presets": {
|
||||
"0": {
|
||||
"title": "Defibrillator"
|
||||
}
|
||||
},
|
||||
"tagRenderings": {
|
||||
"1": {
|
||||
"question": "Befindet sich dieser Defibrillator im Gebäude?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Dieser Defibrillator befindet sich im Gebäude"
|
||||
},
|
||||
"1": {
|
||||
"then": "Dieser Defibrillator befindet sich im Freien"
|
||||
}
|
||||
}
|
||||
},
|
||||
"2": {
|
||||
"question": "Ist dieser Defibrillator frei zugänglich?",
|
||||
"render": "Zugang ist {access}",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Öffentlich zugänglich"
|
||||
},
|
||||
"1": {
|
||||
"then": "Öffentlich zugänglich"
|
||||
},
|
||||
"2": {
|
||||
"then": "Nur für Kunden zugänglich"
|
||||
},
|
||||
"3": {
|
||||
"then": "Nicht für die Öffentlichkeit zugänglich (z.B. nur für das Personal, die Eigentümer, ...)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"4": {
|
||||
"question": "In welchem Stockwerk befindet sich dieser Defibrillator?",
|
||||
"render": "Dieser Defibrallator befindet sich im {level}. Stockwerk"
|
||||
},
|
||||
"5": {
|
||||
"question": "Bitte geben Sie einige Erläuterungen dazu, wo der Defibrillator zu finden ist (in der lokalen Sprache)"
|
||||
},
|
||||
"6": {
|
||||
"question": "Bitte geben Sie einige Erläuterungen dazu, wo der Defibrillator zu finden ist (auf Englisch)"
|
||||
},
|
||||
"7": {
|
||||
"question": "Bitte geben Sie einige Erläuterungen dazu, wo der Defibrillator zu finden ist (auf Französisch)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"drinking_water": {
|
||||
"name": "Trinkwasser",
|
||||
"title": {
|
||||
"render": "Trinkwasser"
|
||||
},
|
||||
"presets": {
|
||||
"0": {
|
||||
"title": "Trinkwasser"
|
||||
}
|
||||
},
|
||||
"tagRenderings": {
|
||||
"2": {
|
||||
"question": "Wie einfach ist es, Wasserflaschen zu füllen?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Es ist einfach, Wasserflaschen nachzufüllen"
|
||||
},
|
||||
"1": {
|
||||
"then": "Wasserflaschen passen möglicherweise nicht"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ghost_bike": {
|
||||
"name": "Geisterrad",
|
||||
"title": {
|
||||
"render": "Geisterrad",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Geisterrad im Gedenken an {name}"
|
||||
}
|
||||
}
|
||||
},
|
||||
"presets": {
|
||||
"0": {
|
||||
"title": "Geisterrad"
|
||||
}
|
||||
},
|
||||
"tagRenderings": {
|
||||
"0": {
|
||||
"render": "Ein <b>Geisterrad</b> ist ein Denkmal für einen Radfahrer, der bei einem Verkehrsunfall ums Leben kam, in Form eines weißen Fahrrades, das dauerhaft in der Nähe des Unfallortes aufgestellt wird."
|
||||
},
|
||||
"2": {
|
||||
"question": "An wen erinnert dieses Geisterrad?<span class='question-subtext'><br/>Bitte respektieren Sie die Privatsphäre - geben Sie den Namen nur an, wenn er weit verbreitet oder auf dem Fahrrad markiert ist. Den Familiennamen können Sie weglassen.</span>",
|
||||
"render": "Im Gedenken an {name}",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Auf dem Fahrrad ist kein Name angegeben"
|
||||
}
|
||||
}
|
||||
},
|
||||
"3": {
|
||||
"question": "Auf welcher Webseite kann man mehr Informationen über das Geisterrad oder den Unfall finden?",
|
||||
"render": "<a href='{source}' target='_blank'>Mehr Informationen</a>"
|
||||
},
|
||||
"4": {
|
||||
"question": "Wie lautet die Inschrift auf diesem Geisterrad?",
|
||||
"render": "<i>{inscription}</i>"
|
||||
}
|
||||
}
|
||||
},
|
||||
"public_bookcase": {
|
||||
"name": "Bücherschränke",
|
||||
"description": "Ein Bücherschrank am Straßenrand mit Büchern, für jedermann zugänglich",
|
||||
"title": {
|
||||
"render": "Bücherschrank",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Öffentlicher Bücherschrank <i>{name}</i>"
|
||||
}
|
||||
}
|
||||
},
|
||||
"presets": {
|
||||
"0": {
|
||||
"title": "Bücherschrank"
|
||||
}
|
||||
},
|
||||
"tagRenderings": {
|
||||
"1": {
|
||||
"render": "Der Name dieses Bücherschrank lautet {name}",
|
||||
"question": "Wie heißt dieser öffentliche Bücherschrank?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Dieser Bücherschrank hat keinen Namen"
|
||||
}
|
||||
}
|
||||
},
|
||||
"2": {
|
||||
"render": "{capacity} Bücher passen in diesen Bücherschrank",
|
||||
"question": "Wie viele Bücher passen in diesen öffentlichen Bücherschrank?"
|
||||
},
|
||||
"3": {
|
||||
"question": "Welche Art von Büchern sind in diesem öffentlichen Bücherschrank zu finden?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Vorwiegend Kinderbücher"
|
||||
},
|
||||
"1": {
|
||||
"then": "Vorwiegend Bücher für Erwachsene"
|
||||
},
|
||||
"2": {
|
||||
"then": "Sowohl Bücher für Kinder als auch für Erwachsene"
|
||||
}
|
||||
}
|
||||
},
|
||||
"4": {
|
||||
"question": "Befindet sich dieser Bücherschrank im Freien?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Dieser Bücherschrank befindet sich im Innenbereich"
|
||||
},
|
||||
"1": {
|
||||
"then": "Dieser Bücherschrank befindet sich im Freien"
|
||||
},
|
||||
"2": {
|
||||
"then": "Dieser Bücherschrank befindet sich im Freien"
|
||||
}
|
||||
}
|
||||
},
|
||||
"5": {
|
||||
"question": "Ist dieser öffentliche Bücherschrank frei zugänglich?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Öffentlich zugänglich"
|
||||
},
|
||||
"1": {
|
||||
"then": "Nur für Kunden zugänglich"
|
||||
}
|
||||
}
|
||||
},
|
||||
"6": {
|
||||
"question": "Wer unterhält diesen öffentlichen Bücherschrank?",
|
||||
"render": "Betrieben von {operator}"
|
||||
},
|
||||
"7": {
|
||||
"question": "Ist dieser öffentliche Bücherschrank Teil eines größeren Netzwerks?",
|
||||
"render": "Dieser Bücherschrank ist Teil von {brand}",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Teil des Netzwerks 'Little Free Library'"
|
||||
},
|
||||
"1": {
|
||||
"then": "Dieser öffentliche Bücherschrank ist nicht Teil eines größeren Netzwerks"
|
||||
}
|
||||
}
|
||||
},
|
||||
"8": {
|
||||
"render": "Die Referenznummer dieses öffentlichen Bücherschranks innerhalb {brand} lautet {ref}",
|
||||
"question": "Wie lautet die Referenznummer dieses öffentlichen Bücherschranks?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Dieser Bücherschrank ist nicht Teil eines größeren Netzwerks"
|
||||
}
|
||||
}
|
||||
},
|
||||
"9": {
|
||||
"question": "Wann wurde dieser öffentliche Bücherschrank installiert?",
|
||||
"render": "Installiert am {start_date}"
|
||||
},
|
||||
"10": {
|
||||
"render": "Weitere Informationen auf <a href='{website}' target='_blank'>der Webseite</a>",
|
||||
"question": "Gibt es eine Webseite mit weiteren Informationen über diesen öffentlichen Bücherschrank?"
|
||||
}
|
||||
}
|
||||
},
|
||||
"toilet": {
|
||||
"name": "Toiletten",
|
||||
"title": {
|
||||
"render": "Toilette"
|
||||
},
|
||||
"presets": {
|
||||
"0": {
|
||||
"title": "Toilette",
|
||||
"description": "Eine öffentlich zugängliche Toilette"
|
||||
},
|
||||
"1": {
|
||||
"title": "Toiletten mit rollstuhlgerechter Toilette",
|
||||
"description": "Eine Toilettenanlage mit mindestens einer rollstuhlgerechten Toilette"
|
||||
}
|
||||
},
|
||||
"tagRenderings": {
|
||||
"1": {
|
||||
"question": "Sind diese Toiletten öffentlich zugänglich?",
|
||||
"render": "Zugang ist {access}",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Öffentlicher Zugang"
|
||||
},
|
||||
"1": {
|
||||
"then": "Nur Zugang für Kunden"
|
||||
},
|
||||
"2": {
|
||||
"then": "Nicht zugänglich"
|
||||
},
|
||||
"3": {
|
||||
"then": "Zugänglich, aber man muss einen Schlüssel für die Eingabe verlangen"
|
||||
}
|
||||
}
|
||||
},
|
||||
"2": {
|
||||
"question": "Können diese Toiletten kostenlos benutzt werden?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Dies sind bezahlte Toiletten"
|
||||
},
|
||||
"1": {
|
||||
"then": "Kostenlose Nutzung"
|
||||
}
|
||||
}
|
||||
},
|
||||
"3": {
|
||||
"question": "Wie viel muss man für diese Toiletten bezahlen?",
|
||||
"render": "Die Gebühr beträgt {charge}"
|
||||
},
|
||||
"4": {
|
||||
"question": "Gibt es eine Toilette für Rollstuhlfahrer?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Es gibt eine Toilette für Rollstuhlfahrer"
|
||||
},
|
||||
"1": {
|
||||
"then": "Kein Zugang für Rollstuhlfahrer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"5": {
|
||||
"question": "Welche Art von Toiletten sind das?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Es gibt nur Sitztoiletten"
|
||||
},
|
||||
"1": {
|
||||
"then": "Hier gibt es nur Pissoirs"
|
||||
},
|
||||
"2": {
|
||||
"then": "Es gibt hier nur Hocktoiletten."
|
||||
},
|
||||
"3": {
|
||||
"then": "Sowohl Sitztoiletten als auch Pissoirs sind hier verfügbar"
|
||||
}
|
||||
}
|
||||
},
|
||||
"6": {
|
||||
"question": "Ist ein Wickeltisch (zum Wechseln der Windeln) vorhanden?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Ein Wickeltisch ist verfügbar"
|
||||
},
|
||||
"1": {
|
||||
"then": "Es ist kein Wickeltisch verfügbar"
|
||||
}
|
||||
}
|
||||
},
|
||||
"7": {
|
||||
"question": "Wo befindet sich der Wickeltisch?",
|
||||
"render": "Die Wickeltabelle befindet sich in {changing_table:location}",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Der Wickeltisch befindet sich in der Damentoilette. "
|
||||
},
|
||||
"1": {
|
||||
"then": "Der Wickeltisch befindet sich in der Herrentoilette. "
|
||||
},
|
||||
"2": {
|
||||
"then": "Der Wickeltisch befindet sich in der Toilette für Rollstuhlfahrer. "
|
||||
},
|
||||
"3": {
|
||||
"then": "Der Wickeltisch befindet sich in einem eigenen Raum. "
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"viewpoint": {
|
||||
"name": "Aussichtspunkt",
|
||||
"description": "Ein schöner Aussichtspunkt oder eine schöne Aussicht. Ideal zum Hinzufügen eines Bildes, wenn keine andere Kategorie passt",
|
||||
"presets": {
|
||||
"0": {
|
||||
"title": "Aussichtspunkt"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"render": "Aussichtspunkt"
|
||||
},
|
||||
"tagRenderings": {
|
||||
"1": {
|
||||
"question": "Möchten Sie eine Beschreibung hinzufügen?"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
1785
langs/layers/en.json
Normal file
1785
langs/layers/en.json
Normal file
File diff suppressed because it is too large
Load diff
57
langs/layers/es.json
Normal file
57
langs/layers/es.json
Normal file
|
@ -0,0 +1,57 @@
|
|||
{
|
||||
"defibrillator": {
|
||||
"name": "Desfibriladores",
|
||||
"title": {
|
||||
"render": "Desfibrilador"
|
||||
},
|
||||
"presets": {
|
||||
"0": {
|
||||
"title": "Desfibrilador"
|
||||
}
|
||||
},
|
||||
"tagRenderings": {
|
||||
"1": {
|
||||
"question": "¿Esté el desfibrilador en interior?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Este desfibrilador está en interior"
|
||||
},
|
||||
"1": {
|
||||
"then": "Este desfibrilador está en exterior"
|
||||
}
|
||||
}
|
||||
},
|
||||
"2": {
|
||||
"question": "¿Está el desfibrilador accesible libremente?",
|
||||
"render": "El acceso es {access}",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Acceso libre"
|
||||
},
|
||||
"1": {
|
||||
"then": "Publicament accesible"
|
||||
},
|
||||
"2": {
|
||||
"then": "Sólo accesible a clientes"
|
||||
},
|
||||
"3": {
|
||||
"then": "No accesible al público en general (ex. sólo accesible a trabajadores, propietarios, ...)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"4": {
|
||||
"question": "¿En qué planta se encuentra el defibrilador localizado?",
|
||||
"render": "El desfibrilador se encuentra en la planta {level}"
|
||||
},
|
||||
"5": {
|
||||
"question": "Da detalles de dónde se puede encontrar el desfibrilador (en el idioma local)"
|
||||
},
|
||||
"6": {
|
||||
"question": "Da detalles de dónde se puede encontrar el desfibrilador (en ingles)"
|
||||
},
|
||||
"7": {
|
||||
"question": "Da detalles de dónde se puede encontrar el desfibrilador (en frances)"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
853
langs/layers/fr.json
Normal file
853
langs/layers/fr.json
Normal file
|
@ -0,0 +1,853 @@
|
|||
{
|
||||
"bench": {
|
||||
"name": "Bancs",
|
||||
"title": {
|
||||
"render": "Banc"
|
||||
},
|
||||
"tagRenderings": {
|
||||
"1": {
|
||||
"render": "Dossier",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Dossier: Oui"
|
||||
},
|
||||
"1": {
|
||||
"then": "Dossier: Non"
|
||||
}
|
||||
},
|
||||
"question": "Ce banc dispose-t-il d'un dossier ?"
|
||||
},
|
||||
"2": {
|
||||
"render": "{seats} places",
|
||||
"question": "De combien de places dispose ce banc ?"
|
||||
},
|
||||
"3": {
|
||||
"render": "Matériau : {material}",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Matériau : bois"
|
||||
},
|
||||
"1": {
|
||||
"then": "Matériau : métal"
|
||||
},
|
||||
"2": {
|
||||
"then": "Matériau: pierre"
|
||||
},
|
||||
"3": {
|
||||
"then": "Matériau : béton"
|
||||
},
|
||||
"4": {
|
||||
"then": "Matériau : plastique"
|
||||
},
|
||||
"5": {
|
||||
"then": "Matériau : acier"
|
||||
}
|
||||
},
|
||||
"question": "De quel matériau ce banc est-il fait ?"
|
||||
},
|
||||
"5": {
|
||||
"render": "Couleur : {colour}",
|
||||
"question": "Quelle est la couleur de ce banc ?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Couleur : marron"
|
||||
},
|
||||
"1": {
|
||||
"then": "Couleur : verte"
|
||||
},
|
||||
"2": {
|
||||
"then": "Couleur : gris"
|
||||
},
|
||||
"3": {
|
||||
"then": "Couleur : blanc"
|
||||
},
|
||||
"4": {
|
||||
"then": "Couleur : rouge"
|
||||
},
|
||||
"5": {
|
||||
"then": "Couleur : noire"
|
||||
},
|
||||
"6": {
|
||||
"then": "Couleur : bleu"
|
||||
},
|
||||
"7": {
|
||||
"then": "Couleur : jaune"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"presets": {
|
||||
"0": {
|
||||
"title": "Banc",
|
||||
"description": "Ajouter un nouveau banc"
|
||||
}
|
||||
}
|
||||
},
|
||||
"bench_at_pt": {
|
||||
"name": "Bancs des arrêts de transport en commun",
|
||||
"title": {
|
||||
"render": "Banc",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Banc d'un arrêt de transport en commun"
|
||||
},
|
||||
"1": {
|
||||
"then": "Banc dans un abri"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tagRenderings": {
|
||||
"1": {
|
||||
"render": "{name}"
|
||||
},
|
||||
"2": {
|
||||
"render": "Banc assis debout"
|
||||
}
|
||||
}
|
||||
},
|
||||
"bike_cafe": {
|
||||
"name": "Café vélo",
|
||||
"title": {
|
||||
"render": "Café Vélo",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Café Vélo <i>{name}</i>"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tagRenderings": {
|
||||
"1": {
|
||||
"question": "Quel est le nom de ce Café vélo",
|
||||
"render": "Ce Café vélo s'appelle {name}"
|
||||
},
|
||||
"2": {
|
||||
"question": "Est-ce que ce Café vélo propose une pompe en libre accès",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Ce Café vélo offre une pompe en libre accès"
|
||||
},
|
||||
"1": {
|
||||
"then": "Ce Café vélo n'offre pas de pompe en libre accès"
|
||||
}
|
||||
}
|
||||
},
|
||||
"3": {
|
||||
"question": "Est-ce qu'il y a des outils pour réparer soi-même son vélo?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Ce Café vélo propose des outils pour réparer son vélo soi-même"
|
||||
},
|
||||
"1": {
|
||||
"then": "Ce Café vélo ne propose pas d'outils pour réparer son vélo soi-même"
|
||||
}
|
||||
}
|
||||
},
|
||||
"4": {
|
||||
"question": "Est-ce que ce Café vélo répare les vélos?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Ce Café vélo répare les vélos"
|
||||
},
|
||||
"1": {
|
||||
"then": "Ce Café vélo ne répare pas les vélos"
|
||||
}
|
||||
}
|
||||
},
|
||||
"5": {
|
||||
"question": "Quel est le site internet de {name}?"
|
||||
},
|
||||
"6": {
|
||||
"question": "Quel est le nom de {name}?"
|
||||
},
|
||||
"7": {
|
||||
"question": "Quel est l'adresse email de {name}?"
|
||||
}
|
||||
},
|
||||
"presets": {
|
||||
"0": {
|
||||
"title": "Café Vélo"
|
||||
}
|
||||
}
|
||||
},
|
||||
"bike_parking": {
|
||||
"name": "Parking à vélo",
|
||||
"presets": {
|
||||
"0": {
|
||||
"title": "Parking à vélo"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"render": "Parking à vélo"
|
||||
},
|
||||
"tagRenderings": {
|
||||
"1": {
|
||||
"question": "Quelle type de parking s'agit il?",
|
||||
"render": "Ceci est un parking à vélo de type {bicycle_parking}",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Arceaux <img style='width: 25%'' src='./assets/layers/bike_parking/staple.svg'>"
|
||||
},
|
||||
"1": {
|
||||
"then": "Pinces-roues <img style='width: 25%'' src='./assets/layers/bike_parking/wall_loops.svg'>"
|
||||
},
|
||||
"2": {
|
||||
"then": "Support guidon <img style='width: 25%'' src='./assets/layers/bike_parking/handlebar_holder.svg'>"
|
||||
},
|
||||
"3": {
|
||||
"then": "Râtelier <img style='width: 25%'' src='./assets/layers/bike_parking/rack.svg'>"
|
||||
},
|
||||
"4": {
|
||||
"then": "Superposé <img style='width: 25%'' src='./assets/layers/bike_parking/two_tier.svg'>"
|
||||
},
|
||||
"5": {
|
||||
"then": "Abri <img style='width: 25%'' src='./assets/layers/bike_parking/shed.svg'>"
|
||||
}
|
||||
}
|
||||
},
|
||||
"4": {
|
||||
"question": "Combien de vélos entrent dans ce parking à vélos (y compris les éventuels vélos de transport) ?",
|
||||
"render": "Place pour {capacity} vélos"
|
||||
},
|
||||
"7": {
|
||||
"question": "Combien de vélos de transport entrent dans ce parking à vélos ?",
|
||||
"render": "Ce parking a de la place pour {capacity:cargo_bike} vélos de transport."
|
||||
}
|
||||
}
|
||||
},
|
||||
"bike_repair_station": {
|
||||
"name": "Station velo (réparation, pompe à vélo)",
|
||||
"title": {
|
||||
"render": "Point station velo avec pompe",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Point de réparation velo"
|
||||
},
|
||||
"1": {
|
||||
"then": "Point de réparation"
|
||||
},
|
||||
"2": {
|
||||
"then": "Pompe cassée"
|
||||
},
|
||||
"3": {
|
||||
"then": "Pompe de vélo <i>{name}</i>"
|
||||
},
|
||||
"4": {
|
||||
"then": "Pompe de vélo"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tagRenderings": {
|
||||
"1": {
|
||||
"question": "Quels services sont valables à cette station vélo?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Il y a seulement une pompe"
|
||||
},
|
||||
"1": {
|
||||
"then": "Il y a seulement des outils (tournevis, pinces...)"
|
||||
},
|
||||
"2": {
|
||||
"then": "Il y a des outils et une pompe"
|
||||
}
|
||||
}
|
||||
},
|
||||
"4": {
|
||||
"question": "Est-ce que cette station vélo a un outils specifique pour réparer la chaîne du velo?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Il y a un outil pour réparer la chaine"
|
||||
},
|
||||
"1": {
|
||||
"then": "Il n'y a pas d'outil pour réparer la chaine"
|
||||
}
|
||||
}
|
||||
},
|
||||
"5": {
|
||||
"question": "Est-ce que cette station vélo à un crochet pour suspendre son velo ou une accroche pour l'élevé?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Il y a un crochet ou une accroche"
|
||||
},
|
||||
"1": {
|
||||
"then": "Il n'y pas de crochet ou d'accroche"
|
||||
}
|
||||
}
|
||||
},
|
||||
"6": {
|
||||
"question": "Est-ce que cette pompe marche t'elle toujours?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "La pompe est cassé"
|
||||
},
|
||||
"1": {
|
||||
"then": "La pompe est opérationnelle"
|
||||
}
|
||||
}
|
||||
},
|
||||
"7": {
|
||||
"question": "Quelles valves sont compatibles?",
|
||||
"render": "Cette pompe est compatible avec les valves suivantes: {valves}",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Sclaverand (aussi appelé Presta)"
|
||||
},
|
||||
"1": {
|
||||
"then": "Dunlop"
|
||||
},
|
||||
"2": {
|
||||
"then": "Schrader (les valves de voitures)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"8": {
|
||||
"question": "Est-ce que cette pompe est électrique?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Pompe manuelle"
|
||||
},
|
||||
"1": {
|
||||
"then": "Pompe électrique"
|
||||
}
|
||||
}
|
||||
},
|
||||
"9": {
|
||||
"question": "Est-ce que la pompe à un manomètre integré?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Il y a un manomètre"
|
||||
},
|
||||
"1": {
|
||||
"then": "Il n'y a pas de manomètre"
|
||||
},
|
||||
"2": {
|
||||
"then": "Il y a un manomètre mais il est cassé"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"presets": {
|
||||
"0": {
|
||||
"title": "Pompe à vélo"
|
||||
},
|
||||
"1": {
|
||||
"title": "Point de réparation vélo avec pompe"
|
||||
},
|
||||
"2": {
|
||||
"title": "Point de réparation vélo sans pompe"
|
||||
}
|
||||
}
|
||||
},
|
||||
"bike_shop": {
|
||||
"name": "Magasin ou réparateur de vélo",
|
||||
"title": {
|
||||
"render": "Magasin ou réparateur de vélo",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Magasin de sport <i>{name}</i>"
|
||||
},
|
||||
"3": {
|
||||
"then": "Réparateur de vélo <i>{name}</i>"
|
||||
},
|
||||
"4": {
|
||||
"then": "Magasin de vélo <i>{name}</i>"
|
||||
},
|
||||
"5": {
|
||||
"then": "Magasin ou réparateur de vélo <i>{name}</i>"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tagRenderings": {
|
||||
"2": {
|
||||
"question": "Quel est le nom du magasin de vélo?",
|
||||
"render": "Ce magasin s'appelle {name}"
|
||||
},
|
||||
"3": {
|
||||
"question": "Quel est le site internet de {name}?"
|
||||
},
|
||||
"4": {
|
||||
"question": "Quel est le nom de {name}?"
|
||||
},
|
||||
"5": {
|
||||
"question": "Quel est l'adresse email de {name}?"
|
||||
},
|
||||
"9": {
|
||||
"question": "Est-ce que ce magasin vend des vélos?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Ce magasin vend des vélos"
|
||||
},
|
||||
"1": {
|
||||
"then": "Ce magasin ne vend pas de vélo"
|
||||
}
|
||||
}
|
||||
},
|
||||
"10": {
|
||||
"question": "Est-ce que ce magasin répare des vélos?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Ce magasin répare des vélos"
|
||||
},
|
||||
"1": {
|
||||
"then": "Ce magasin ne répare pas les vélos"
|
||||
},
|
||||
"2": {
|
||||
"then": "Ce magasin ne répare seulement les vélos achetés là-bas"
|
||||
},
|
||||
"3": {
|
||||
"then": "Ce magasin ne répare seulement des marques spécifiques"
|
||||
}
|
||||
}
|
||||
},
|
||||
"11": {
|
||||
"question": "Est-ce ce magasin loue des vélos?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Ce magasin loue des vélos"
|
||||
},
|
||||
"1": {
|
||||
"then": "Ce magasin ne loue pas de vélos"
|
||||
}
|
||||
}
|
||||
},
|
||||
"12": {
|
||||
"question": "Est-ce ce magasin vend des vélos d'occasion",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Ce magasin vend des vélos d'occasion"
|
||||
},
|
||||
"1": {
|
||||
"then": "Ce magasin ne vend pas de vélos d'occasion"
|
||||
},
|
||||
"2": {
|
||||
"then": "Ce magasin vend seulement des vélos d'occasion"
|
||||
}
|
||||
}
|
||||
},
|
||||
"13": {
|
||||
"question": "Est-ce que ce magasin offre une pompe en accès libre?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Ce magasin offre une pompe en acces libre"
|
||||
},
|
||||
"1": {
|
||||
"then": "Ce magasin n'offre pas de pompe en libre accès"
|
||||
}
|
||||
}
|
||||
},
|
||||
"14": {
|
||||
"question": "Est-ce qu'il y a des outils pour réparer son vélo dans ce magasin?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Ce magasin offre des outils pour réparer son vélo soi-même"
|
||||
},
|
||||
"1": {
|
||||
"then": "Ce magasin n'offre pas des outils pour réparer son vélo soi-même"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"presets": {
|
||||
"0": {
|
||||
"title": "Magasin et réparateur de vélo"
|
||||
}
|
||||
}
|
||||
},
|
||||
"bike_themed_object": {
|
||||
"name": "Objet cycliste",
|
||||
"title": {
|
||||
"render": "Objet cycliste"
|
||||
}
|
||||
},
|
||||
"defibrillator": {
|
||||
"name": "Défibrillateurs",
|
||||
"title": {
|
||||
"render": "Défibrillateur"
|
||||
},
|
||||
"presets": {
|
||||
"0": {
|
||||
"title": "Défibrillateur"
|
||||
}
|
||||
},
|
||||
"tagRenderings": {
|
||||
"1": {
|
||||
"question": "Ce défibrillateur est-il disposé en intérieur ?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Ce défibrillateur est en intérieur (dans un batiment)"
|
||||
},
|
||||
"1": {
|
||||
"then": "Ce défibrillateur est situé en extérieur"
|
||||
}
|
||||
}
|
||||
},
|
||||
"2": {
|
||||
"question": "Ce défibrillateur est-il librement accessible ?",
|
||||
"render": "{access} accessible",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Librement accessible"
|
||||
},
|
||||
"1": {
|
||||
"then": "Librement accessible"
|
||||
},
|
||||
"2": {
|
||||
"then": "Réservé aux clients du lieu"
|
||||
},
|
||||
"3": {
|
||||
"then": "Non accessible au public (par exemple réservé au personnel, au propriétaire, ...)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"4": {
|
||||
"question": "À quel étage est situé ce défibrillateur ?",
|
||||
"render": "Ce défibrillateur est à l'étage {level}"
|
||||
},
|
||||
"5": {
|
||||
"question": "Veuillez indiquez plus précisément où se situe le défibrillateur (dans la langue local)"
|
||||
},
|
||||
"6": {
|
||||
"question": "Veuillez indiquez plus précisément où se situe le défibrillateur (en englais)"
|
||||
},
|
||||
"7": {
|
||||
"question": "Veuillez indiquez plus précisément où se situe le défibrillateur (en français)"
|
||||
},
|
||||
"11": {
|
||||
"render": "Numéro de téléphone pour questions sur le défibrillateur: <a href='tel:{phone}'>{phone}</a>",
|
||||
"question": "Quel est le numéro de téléphone pour questions sur le défibrillateur?"
|
||||
}
|
||||
}
|
||||
},
|
||||
"drinking_water": {
|
||||
"name": "Eau potable",
|
||||
"title": {
|
||||
"render": "Eau potable"
|
||||
},
|
||||
"presets": {
|
||||
"0": {
|
||||
"title": "Eau potable"
|
||||
}
|
||||
}
|
||||
},
|
||||
"public_bookcase": {
|
||||
"name": "Microbibliothèque",
|
||||
"description": "Une armoire ou une boite contenant des livres en libre accès",
|
||||
"title": {
|
||||
"render": "Microbibliothèque",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Microbibliothèque <i>{name}</i>"
|
||||
}
|
||||
}
|
||||
},
|
||||
"presets": {
|
||||
"0": {
|
||||
"title": "Microbibliothèque"
|
||||
}
|
||||
},
|
||||
"tagRenderings": {
|
||||
"1": {
|
||||
"render": "Le nom de cette microbibliothèque est {name}",
|
||||
"question": "Quel est le nom de cette microbibliothèque ?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Cette microbibliothèque n'a pas de nom"
|
||||
}
|
||||
}
|
||||
},
|
||||
"2": {
|
||||
"render": "{capacity} livres rentrent dans cette microbibliothèque",
|
||||
"question": "Combien de livre rentrent dans cette microbibliothèque ?"
|
||||
},
|
||||
"3": {
|
||||
"question": "Quel type de livres peuvent être trouvés dans cette microbibliothèque ?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Livres pour enfants"
|
||||
},
|
||||
"1": {
|
||||
"then": "Livres pour les adultes"
|
||||
},
|
||||
"2": {
|
||||
"then": "Livres pour enfants et adultes également"
|
||||
}
|
||||
}
|
||||
},
|
||||
"4": {
|
||||
"question": "Cette microbiliothèque est-elle en extérieur ?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Cette microbibliothèque est en intérieur"
|
||||
},
|
||||
"1": {
|
||||
"then": "Cette microbibliothèque est en extérieur"
|
||||
},
|
||||
"2": {
|
||||
"then": "Cette microbibliothèque est en extérieur"
|
||||
}
|
||||
}
|
||||
},
|
||||
"5": {
|
||||
"question": "Cette microbibliothèque est-elle librement accèssible ?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Accèssible au public"
|
||||
},
|
||||
"1": {
|
||||
"then": "Accèssible aux clients"
|
||||
}
|
||||
}
|
||||
},
|
||||
"6": {
|
||||
"question": "Qui entretien cette microbibliothèque",
|
||||
"render": "Entretenue par {operator}"
|
||||
},
|
||||
"7": {
|
||||
"question": "Cette microbibliothèque fait-elle partie d'un réseau/groupe ?",
|
||||
"render": "Cette microbibliothèque fait partie du groupe {brand}",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Fait partie du réseau 'Little Free Library'"
|
||||
},
|
||||
"1": {
|
||||
"then": "Cette microbibliothèque ne fait pas partie d'un réseau/groupe"
|
||||
}
|
||||
}
|
||||
},
|
||||
"8": {
|
||||
"render": "Cette microbibliothèque du réseau {brand} possède le numéro {ref}",
|
||||
"question": "Quelle est le numéro de référence de cette microbibliothèque ?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Cette microbibliothèque ne fait pas partie d'un réseau/groupe"
|
||||
}
|
||||
}
|
||||
},
|
||||
"9": {
|
||||
"question": "Quand a été installée cette microbibliothèque ?",
|
||||
"render": "Installée le {start_date}"
|
||||
},
|
||||
"10": {
|
||||
"render": "Plus d'info sur <a href='{website} target='_blank'>le site web</a>",
|
||||
"question": "Existe-t-il un site web avec plus d'information sur cette microbibliothèque ?"
|
||||
}
|
||||
}
|
||||
},
|
||||
"sport_pitch": {
|
||||
"name": "Terrains de sport",
|
||||
"title": {
|
||||
"render": "Terrain de sport"
|
||||
},
|
||||
"description": "Un terrain de sport",
|
||||
"tagRenderings": {
|
||||
"1": {
|
||||
"render": "Ici on joue au {sport}",
|
||||
"question": "À quel sport peut-on jouer ici ?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Ici on peut jouer au basket"
|
||||
},
|
||||
"1": {
|
||||
"then": "Ici on joue au foot"
|
||||
},
|
||||
"2": {
|
||||
"then": "C'est une table de ping-pong"
|
||||
},
|
||||
"3": {
|
||||
"then": "Ici on peut jouer au tennis"
|
||||
},
|
||||
"4": {
|
||||
"then": "Ici on peut jouer au korfbal"
|
||||
},
|
||||
"5": {
|
||||
"then": "Ici on peut jouer au basket"
|
||||
}
|
||||
}
|
||||
},
|
||||
"2": {
|
||||
"question": "De quelle surface est fait ce terrain de sport ?",
|
||||
"render": "La surface est <b>{surface}</b>",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "La surface est de l'<b>herbe</b>"
|
||||
},
|
||||
"1": {
|
||||
"then": "La surface est du <b>sable</b>"
|
||||
},
|
||||
"2": {
|
||||
"then": "La surface est des <b>pavés</b>"
|
||||
},
|
||||
"3": {
|
||||
"then": "La surface est de l'<b>asphalte</b>"
|
||||
},
|
||||
"4": {
|
||||
"then": "La surface est du <b>béton</b>"
|
||||
}
|
||||
}
|
||||
},
|
||||
"3": {
|
||||
"question": "Est-ce que ce terrain de sport est accessible au public ?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Accessible au public"
|
||||
},
|
||||
"1": {
|
||||
"then": "Accès limité (par exemple uniquement sur réservation, à certains horaires, ...)"
|
||||
},
|
||||
"2": {
|
||||
"then": "Accessible uniquement aux membres du club"
|
||||
},
|
||||
"3": {
|
||||
"then": "Privé - Pas accessible au public"
|
||||
}
|
||||
}
|
||||
},
|
||||
"4": {
|
||||
"question": "Doit-on réserver pour utiliser ce terrain de sport ?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Il est obligatoire de réserver pour utiliser ce terrain de sport"
|
||||
},
|
||||
"1": {
|
||||
"then": "Il est recommendé de réserver pour utiliser ce terrain de sport"
|
||||
},
|
||||
"2": {
|
||||
"then": "Il est possible de réserver, mais ce n'est pas nécéssaire pour utiliser ce terrain de sport"
|
||||
},
|
||||
"3": {
|
||||
"then": "On ne peux pas réserver"
|
||||
}
|
||||
}
|
||||
},
|
||||
"5": {
|
||||
"question": "Quel est le numéro de téléphone du gérant ?"
|
||||
},
|
||||
"6": {
|
||||
"question": "Quel est l'adresse courriel du gérant ?"
|
||||
},
|
||||
"7": {
|
||||
"question": "Quand ce terrain est-il accessible ?",
|
||||
"mappings": {
|
||||
"1": {
|
||||
"then": "Accessible en permanence"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"presets": {
|
||||
"0": {
|
||||
"title": "Table de ping-pong"
|
||||
},
|
||||
"1": {
|
||||
"title": "Terrain de sport"
|
||||
}
|
||||
}
|
||||
},
|
||||
"toilet": {
|
||||
"name": "Toilettes",
|
||||
"title": {
|
||||
"render": "Toilettes"
|
||||
},
|
||||
"presets": {
|
||||
"0": {
|
||||
"title": "Toilettes",
|
||||
"description": "Des toilettes"
|
||||
},
|
||||
"1": {
|
||||
"title": "Toilettes accessible aux personnes à mobilité réduite",
|
||||
"description": "Toilettes avec au moins un WC accessible aux personnes à mobilité réduite"
|
||||
}
|
||||
},
|
||||
"tagRenderings": {
|
||||
"1": {
|
||||
"question": "Ces toilettes sont-elles accessibles publiquement ?",
|
||||
"render": "L'accès est {access}",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Accès publique"
|
||||
},
|
||||
"1": {
|
||||
"then": "Accès réservé aux clients"
|
||||
},
|
||||
"2": {
|
||||
"then": "WC privés"
|
||||
},
|
||||
"3": {
|
||||
"then": "Accessible, mais vous devez demander la clé"
|
||||
}
|
||||
}
|
||||
},
|
||||
"2": {
|
||||
"question": "Ces toilettes sont-elles payantes",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Toilettes payantes"
|
||||
},
|
||||
"1": {
|
||||
"then": "Toilettes gratuites"
|
||||
}
|
||||
}
|
||||
},
|
||||
"3": {
|
||||
"question": "Quel est le prix d'accès de ces toilettes ?",
|
||||
"render": "Le prix est {charge}"
|
||||
},
|
||||
"4": {
|
||||
"question": "Un WC réservé aux personnes à mobilité réduite est-il présent ?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Il y a un WC réservé pour les personnes à mobilité réduite"
|
||||
},
|
||||
"1": {
|
||||
"then": "Non accessible aux personnes à mobilité réduite"
|
||||
}
|
||||
}
|
||||
},
|
||||
"5": {
|
||||
"question": "De quel type sont ces toilettes ?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Il y a uniquement des WC assis"
|
||||
},
|
||||
"1": {
|
||||
"then": "Il y a uniquement des urinoirs"
|
||||
},
|
||||
"2": {
|
||||
"then": "Il y a uniquement des WC turques"
|
||||
},
|
||||
"3": {
|
||||
"then": "Il y a des WC assis et des urinoirs"
|
||||
}
|
||||
}
|
||||
},
|
||||
"6": {
|
||||
"question": "Ces WC disposent-ils d'une table à langer ?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Une table à langer est disponible"
|
||||
},
|
||||
"1": {
|
||||
"then": "Aucune table à langer"
|
||||
}
|
||||
}
|
||||
},
|
||||
"7": {
|
||||
"question": "Où se situe la table à langer ?",
|
||||
"render": "Emplacement de la table à langer : {changing_table:location}",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "La table à langer se situe dans les WC pour femmes. "
|
||||
},
|
||||
"1": {
|
||||
"then": "La table à langer se situe dans les WC pour hommes. "
|
||||
},
|
||||
"2": {
|
||||
"then": "La table à langer se situe dans les WC pour personnes à mobilité réduite. "
|
||||
},
|
||||
"3": {
|
||||
"then": "La table à langer se situe dans un espace dédié. "
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
382
langs/layers/gl.json
Normal file
382
langs/layers/gl.json
Normal file
|
@ -0,0 +1,382 @@
|
|||
{
|
||||
"bike_cafe": {
|
||||
"name": "Café de ciclistas",
|
||||
"title": {
|
||||
"render": "Café de ciclistas",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Café de ciclistas <i>{name}</i>"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tagRenderings": {
|
||||
"1": {
|
||||
"question": "Cal é o nome deste café de ciclistas?",
|
||||
"render": "Este café de ciclistas chámase {name}"
|
||||
},
|
||||
"2": {
|
||||
"question": "Este café de ciclistas ofrece unha bomba de ar para que calquera persoa poida usala?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Este café de ciclistas ofrece unha bomba de ar"
|
||||
},
|
||||
"1": {
|
||||
"then": "Este café de ciclistas non ofrece unha bomba de ar"
|
||||
}
|
||||
}
|
||||
},
|
||||
"3": {
|
||||
"question": "Hai ferramentas aquí para arranxar a túa propia bicicleta?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Hai ferramentas aquí para arranxar a túa propia bicicleta"
|
||||
},
|
||||
"1": {
|
||||
"then": "Non hai ferramentas aquí para arranxar a túa propia bicicleta"
|
||||
}
|
||||
}
|
||||
},
|
||||
"4": {
|
||||
"question": "Este café de ciclistas arranxa bicicletas?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Este café de ciclistas arranxa bicicletas"
|
||||
},
|
||||
"1": {
|
||||
"then": "Este café de ciclistas non arranxa bicicletas"
|
||||
}
|
||||
}
|
||||
},
|
||||
"5": {
|
||||
"question": "Cal é a páxina web de {name}?"
|
||||
},
|
||||
"6": {
|
||||
"question": "Cal é o número de teléfono de {name}?"
|
||||
},
|
||||
"7": {
|
||||
"question": "Cal é o enderezo de correo electrónico de {name}?"
|
||||
}
|
||||
},
|
||||
"presets": {
|
||||
"0": {
|
||||
"title": "Café de ciclistas"
|
||||
}
|
||||
}
|
||||
},
|
||||
"bike_parking": {
|
||||
"name": "Aparcadoiro de bicicletas",
|
||||
"presets": {
|
||||
"0": {
|
||||
"title": "Aparcadoiro de bicicletas"
|
||||
}
|
||||
},
|
||||
"title": {
|
||||
"render": "Aparcadoiro de bicicletas"
|
||||
},
|
||||
"tagRenderings": {
|
||||
"1": {
|
||||
"question": "Que tipo de aparcadoiro de bicicletas é?",
|
||||
"render": "Este é un aparcadoiro de bicicletas do tipo: {bicycle_parking}",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "De roda (Stands) <img style='width: 25%'' src='./assets/layers/bike_parking/staple.svg'>"
|
||||
},
|
||||
"1": {
|
||||
"then": "Aros <img style='width: 25%'' src='./assets/layers/bike_parking/wall_loops.svg'>"
|
||||
},
|
||||
"2": {
|
||||
"then": "Cadeado para guiador <img style='width: 25%'' src='./assets/layers/bike_parking/handlebar_holder.svg'>"
|
||||
},
|
||||
"3": {
|
||||
"then": "Cremalleira <img style='width: 25%'' src='./assets/layers/bike_parking/rack.svg'>"
|
||||
},
|
||||
"4": {
|
||||
"then": "Dobre cremalleira <img style='width: 25%'' src='./assets/layers/bike_parking/two_tier.svg'>"
|
||||
},
|
||||
"5": {
|
||||
"then": "Abeiro <img style='width: 25%'' src='./assets/layers/bike_parking/shed.svg'>"
|
||||
}
|
||||
}
|
||||
},
|
||||
"3": {
|
||||
"question": "Este aparcadoiro está cuberto? Tamén escolle \"cuberto\" para aparcadoiros interiores.",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Este aparcadoiro está cuberto (ten un teito)"
|
||||
},
|
||||
"1": {
|
||||
"then": "Este aparcadoiro non está cuberto"
|
||||
}
|
||||
}
|
||||
},
|
||||
"4": {
|
||||
"question": "Cantas bicicletas caben neste aparcadoiro de bicicletas (incluídas as posíbeis bicicletas de carga)?",
|
||||
"render": "Lugar para {capacity} bicicletas"
|
||||
},
|
||||
"6": {
|
||||
"question": "Este aparcadoiro de bicicletas ten espazo para bicicletas de carga?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Este aparcadoiro ten espazo para bicicletas de carga."
|
||||
},
|
||||
"1": {
|
||||
"then": "Este aparcadoiro ten espazos designados (oficiais) para bicicletas de carga."
|
||||
},
|
||||
"2": {
|
||||
"then": "Non está permitido aparcar bicicletas de carga"
|
||||
}
|
||||
}
|
||||
},
|
||||
"7": {
|
||||
"question": "Cantas bicicletas de carga caben neste aparcadoiro de bicicletas?",
|
||||
"render": "Neste aparcadoiro caben {capacity:cargo_bike} bicicletas de carga"
|
||||
}
|
||||
}
|
||||
},
|
||||
"bike_repair_station": {
|
||||
"name": "Estación de bicicletas (arranxo, bomba de ar ou ambos)",
|
||||
"title": {
|
||||
"render": "Estación de bicicletas (arranxo e bomba de ar)",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Estación de arranxo de bicicletas"
|
||||
},
|
||||
"1": {
|
||||
"then": "Estación de arranxo de bicicletas"
|
||||
},
|
||||
"2": {
|
||||
"then": "Bomba de ar estragada"
|
||||
},
|
||||
"3": {
|
||||
"then": "Bomba de ar <i>{name}</i>"
|
||||
},
|
||||
"4": {
|
||||
"then": "Bomba de ar"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tagRenderings": {
|
||||
"1": {
|
||||
"question": "Que servizos están dispoñíbeis nesta estación de bicicletas?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Só hai unha bomba de ar presente"
|
||||
},
|
||||
"1": {
|
||||
"then": "Só hai ferramentas (desaparafusadores, alicates...) presentes"
|
||||
},
|
||||
"2": {
|
||||
"then": "Hai ferramentas e unha bomba de ar presentes"
|
||||
}
|
||||
}
|
||||
},
|
||||
"4": {
|
||||
"question": "Esta estación de arranxo de bicicletas ten unha ferramenta especial para arranxar a cadea da túa bicicleta?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Hai unha ferramenta para a cadea"
|
||||
},
|
||||
"1": {
|
||||
"then": "Non hai unha ferramenta para a cadea"
|
||||
}
|
||||
}
|
||||
},
|
||||
"5": {
|
||||
"question": "Esta estación de bicicletas ten un guindastre para pendurar a túa bicicleta ou un soporte para elevala?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Hai un guindastre ou soporte"
|
||||
},
|
||||
"1": {
|
||||
"then": "Non hai un guindastre ou soporte"
|
||||
}
|
||||
}
|
||||
},
|
||||
"6": {
|
||||
"question": "Segue a funcionar a bomba de ar?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "A bomba de ar está estragada"
|
||||
},
|
||||
"1": {
|
||||
"then": "A bomba de ar está operativa"
|
||||
}
|
||||
}
|
||||
},
|
||||
"7": {
|
||||
"question": "Que válvulas son compatíbeis?",
|
||||
"render": "Esta bomba de ar admite as seguintes válvulas: {valves}",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Sclaverand (tamén coñecido como Presta)"
|
||||
},
|
||||
"1": {
|
||||
"then": "Dunlop"
|
||||
},
|
||||
"2": {
|
||||
"then": "Schrader (para automóbiles)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"8": {
|
||||
"question": "Esta é unha bomba de ar eléctrica?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Bomba de ar manual"
|
||||
},
|
||||
"1": {
|
||||
"then": "Bomba de ar eléctrica"
|
||||
}
|
||||
}
|
||||
},
|
||||
"9": {
|
||||
"question": "Ten a bomba de ar un indicador de presión ou un manómetro?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Hai manómetro"
|
||||
},
|
||||
"1": {
|
||||
"then": "Non hai manómetro"
|
||||
},
|
||||
"2": {
|
||||
"then": "Hai manómetro pero está estragado"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"presets": {
|
||||
"0": {
|
||||
"title": "Bomba de ar"
|
||||
},
|
||||
"1": {
|
||||
"title": "Estación de arranxo de bicicletas con bomba de ar"
|
||||
},
|
||||
"2": {
|
||||
"title": "Estación de arranxo de bicicletas sin bomba de ar"
|
||||
}
|
||||
}
|
||||
},
|
||||
"bike_shop": {
|
||||
"name": "Tenda/arranxo de bicicletas",
|
||||
"title": {
|
||||
"render": "Tenda/arranxo de bicicletas",
|
||||
"mappings": {
|
||||
"3": {
|
||||
"then": "Arranxo de bicicletas <i>{name}</i>"
|
||||
},
|
||||
"4": {
|
||||
"then": "Tenda de bicicletas <i>{name}</i>"
|
||||
},
|
||||
"5": {
|
||||
"then": "Tenda/arranxo de bicicletas <i>{name}</i>"
|
||||
}
|
||||
}
|
||||
},
|
||||
"tagRenderings": {
|
||||
"2": {
|
||||
"question": "Cal é o nome desta tenda de bicicletas?",
|
||||
"render": "Esta tenda de bicicletas chámase {name}"
|
||||
},
|
||||
"3": {
|
||||
"question": "Cal é a páxina web de {name}?"
|
||||
},
|
||||
"4": {
|
||||
"question": "Cal é o número de teléfono de {name}?"
|
||||
},
|
||||
"5": {
|
||||
"question": "Cal é o enderezo de correo electrónico de {name}?"
|
||||
},
|
||||
"9": {
|
||||
"question": "Esta tenda vende bicicletas?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Esta tenda vende bicicletas"
|
||||
},
|
||||
"1": {
|
||||
"then": "Esta tenda non vende bicicletas"
|
||||
}
|
||||
}
|
||||
},
|
||||
"10": {
|
||||
"question": "Esta tenda arranxa bicicletas?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Esta tenda arranxa bicicletas"
|
||||
},
|
||||
"1": {
|
||||
"then": "Esta tenda non arranxa bicicletas"
|
||||
},
|
||||
"2": {
|
||||
"then": "Esta tenda só arranxa bicicletas mercadas aquí"
|
||||
},
|
||||
"3": {
|
||||
"then": "Esta tenda só arranxa bicicletas dunha certa marca"
|
||||
}
|
||||
}
|
||||
},
|
||||
"11": {
|
||||
"question": "Esta tenda aluga bicicletas?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Esta tenda aluga bicicletas"
|
||||
},
|
||||
"1": {
|
||||
"then": "Esta tenda non aluga bicicletas"
|
||||
}
|
||||
}
|
||||
},
|
||||
"12": {
|
||||
"question": "Esta tenda vende bicicletas de segunda man?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Esta tenda vende bicicletas de segunda man"
|
||||
},
|
||||
"1": {
|
||||
"then": "Esta tenda non vende bicicletas de segunda man"
|
||||
},
|
||||
"2": {
|
||||
"then": "Esta tenda só vende bicicletas de segunda man"
|
||||
}
|
||||
}
|
||||
},
|
||||
"13": {
|
||||
"question": "Esta tenda ofrece unha bomba de ar para uso de calquera persoa?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Esta tenda ofrece unha bomba de ar para uso de calquera persoa"
|
||||
},
|
||||
"1": {
|
||||
"then": "Esta tenda non ofrece unha bomba de ar para uso de calquera persoa"
|
||||
}
|
||||
}
|
||||
},
|
||||
"14": {
|
||||
"question": "Hai ferramentas aquí para arranxar a túa propia bicicleta?",
|
||||
"mappings": {
|
||||
"0": {
|
||||
"then": "Hai ferramentas aquí para arranxar a túa propia bicicleta"
|
||||
},
|
||||
"1": {
|
||||
"then": "Non hai ferramentas aquí para arranxar a túa propia bicicleta"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"presets": {
|
||||
"0": {
|
||||
"title": "Tenda/arranxo de bicicletas"
|
||||
}
|
||||
}
|
||||
},
|
||||
"drinking_water": {
|
||||
"name": "Auga potábel",
|
||||
"title": {
|
||||
"render": "Auga potábel"
|
||||
},
|
||||
"presets": {
|
||||
"0": {
|
||||
"title": "Auga potábel"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
1732
langs/layers/nl.json
Normal file
1732
langs/layers/nl.json
Normal file
File diff suppressed because it is too large
Load diff
|
@ -12,230 +12,248 @@ import {Translation} from "../UI/i18n/Translation";
|
|||
// It spits out an overview of those to be used to load them
|
||||
|
||||
interface LayersAndThemes {
|
||||
themes: any[] , layers: {parsed: any, path: string}[]
|
||||
themes: any[],
|
||||
layers: { parsed: any, path: string }[]
|
||||
}
|
||||
|
||||
function loadThemesAndLayers():LayersAndThemes{
|
||||
|
||||
const layerFiles = ScriptUtils.readDirRecSync("./assets/layers")
|
||||
.filter(path => path.indexOf(".json") > 0)
|
||||
.filter(path => path.indexOf("license_info.json") < 0)
|
||||
.map(path => {
|
||||
try {
|
||||
const parsed = JSON.parse(readFileSync(path, "UTF8"));
|
||||
return {parsed: parsed, path: path}
|
||||
} catch (e) {
|
||||
console.error("Could not parse file ", "./assets/layers/" + path, "due to ", e)
|
||||
}
|
||||
})
|
||||
const themeFiles: any[] = ScriptUtils.readDirRecSync("./assets/themes")
|
||||
.filter(path => path.endsWith(".json"))
|
||||
.filter(path => path.indexOf("license_info.json") < 0)
|
||||
.map(path => {
|
||||
try{
|
||||
return JSON.parse(readFileSync(path, "UTF8"));
|
||||
}catch(e){
|
||||
console.error("Could not read file ", path, "due to ", e)
|
||||
throw e
|
||||
}
|
||||
});
|
||||
|
||||
console.log("Discovered", layerFiles.length, "layers and", themeFiles.length, "themes\n")
|
||||
return {
|
||||
layers: layerFiles,
|
||||
themes: themeFiles
|
||||
}
|
||||
}
|
||||
|
||||
function writeFiles(lt: LayersAndThemes){
|
||||
writeFileSync("./assets/generated/known_layers_and_themes.json", JSON.stringify({
|
||||
"layers": lt.layers.map(l => l.parsed),
|
||||
"themes": lt.themes
|
||||
}))
|
||||
}
|
||||
|
||||
function validateLayer(layerJson: LayerConfigJson, path: string, knownPaths: Set<string>, context?: string): string[] {
|
||||
let errorCount = [];
|
||||
if (layerJson["overpassTags"] !== undefined) {
|
||||
errorCount.push("Layer " + layerJson.id + "still uses the old 'overpassTags'-format. Please use \"source\": {\"osmTags\": <tags>}' instead of \"overpassTags\": <tags> (note: this isn't your fault, the custom theme generator still spits out the old format)")
|
||||
}
|
||||
try {
|
||||
const layer = new LayerConfig(layerJson, "test", true)
|
||||
const images = Array.from(layer.ExtractImages())
|
||||
const remoteImages = images.filter(img => img.indexOf("http") == 0)
|
||||
for (const remoteImage of remoteImages) {
|
||||
errorCount.push("Found a remote image: " + remoteImage + " in layer " + layer.id + ", please download it. You can use the fixTheme script to automate this")
|
||||
}
|
||||
const expected: string = `assets/layers/${layer.id}/${layer.id}.json`
|
||||
if (path != undefined && path.indexOf(expected) < 0) {
|
||||
errorCount.push("Layer is in an incorrect place. The path is " + path + ", but expected " + expected)
|
||||
}
|
||||
|
||||
for (const image of images) {
|
||||
if(image.indexOf("{") >= 0){
|
||||
console.warn("Ignoring image with { in the path: ", image)
|
||||
continue
|
||||
}
|
||||
|
||||
if (!knownPaths.has(image)) {
|
||||
const ctx = context === undefined ? "" : ` in a layer defined in the theme ${context}`
|
||||
errorCount.push(`Image with path ${image} not found or not attributed; it is used in ${layer.id}${ctx}`)
|
||||
}
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
return [`Layer ${layerJson.id}` ?? JSON.stringify(layerJson).substring(0, 50) + " is invalid: " + e]
|
||||
}
|
||||
return errorCount
|
||||
}
|
||||
|
||||
function validateTranslationCompletenessOfObject(object: any, expectedLanguages: string[], context: string) {
|
||||
const missingTranlations = []
|
||||
const translations: {tr: Translation, context: string}[] = [];
|
||||
const queue: {object: any, context: string}[] = [{object: object, context: context}]
|
||||
|
||||
while (queue.length > 0) {
|
||||
const item = queue.pop();
|
||||
const o = item.object
|
||||
for (const key in o) {
|
||||
const v = o[key];
|
||||
if (v === undefined) {
|
||||
continue;
|
||||
}
|
||||
if (v instanceof Translation || v?.translations !== undefined) {
|
||||
translations.push({tr: v, context: item.context});
|
||||
} else if (
|
||||
["string", "function", "boolean", "number"].indexOf(typeof (v)) < 0) {
|
||||
queue.push({object: v, context: item.context + "." + key})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const missing = {}
|
||||
const present = {}
|
||||
for (const ln of expectedLanguages) {
|
||||
missing[ln] = 0;
|
||||
present[ln] = 0;
|
||||
for (const translation of translations) {
|
||||
if (translation.tr.translations["*"] !== undefined) {
|
||||
continue;
|
||||
}
|
||||
const txt = translation.tr.translations[ln];
|
||||
const isMissing = txt === undefined || txt === "" || txt.toLowerCase().indexOf("todo") >= 0;
|
||||
if (isMissing) {
|
||||
missingTranlations.push(`${translation.context},${ln},${translation.tr.txt}`)
|
||||
missing[ln]++
|
||||
} else {
|
||||
present[ln]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let message = `Translation completeness for ${context}`
|
||||
let isComplete = true;
|
||||
for (const ln of expectedLanguages) {
|
||||
const amiss = missing[ln];
|
||||
const ok = present[ln];
|
||||
const total = amiss + ok;
|
||||
message += ` ${ln}: ${ok}/${total}`
|
||||
if (ok !== total) {
|
||||
isComplete = false;
|
||||
}
|
||||
}
|
||||
return missingTranlations
|
||||
|
||||
}
|
||||
|
||||
function main(args: string[]) {
|
||||
|
||||
const lt = loadThemesAndLayers();
|
||||
const layerFiles = lt.layers;
|
||||
const themeFiles = lt.themes;
|
||||
|
||||
console.log(" ---------- VALIDATING ---------")
|
||||
const licensePaths = []
|
||||
for (const i in licenses) {
|
||||
licensePaths.push(licenses[i].path)
|
||||
}
|
||||
const knownPaths = new Set<string>(licensePaths)
|
||||
|
||||
let layerErrorCount = []
|
||||
const knownLayerIds = new Map<string, LayerConfig>();
|
||||
for (const layerFile of layerFiles) {
|
||||
|
||||
layerErrorCount.push(...validateLayer(layerFile.parsed, layerFile.path, knownPaths))
|
||||
knownLayerIds.set(layerFile.parsed.id, new LayerConfig(layerFile.parsed))
|
||||
}
|
||||
|
||||
let themeErrorCount = []
|
||||
let missingTranslations = []
|
||||
for (const themeFile of themeFiles) {
|
||||
if (typeof themeFile.language === "string") {
|
||||
themeErrorCount.push("The theme " + themeFile.id + " has a string as language. Please use a list of strings")
|
||||
}
|
||||
for (const layer of themeFile.layers) {
|
||||
if (typeof layer === "string") {
|
||||
if (!knownLayerIds.has(layer)) {
|
||||
themeErrorCount.push(`Unknown layer id: ${layer} in theme ${themeFile.id}`)
|
||||
} else {
|
||||
const layerConfig = knownLayerIds.get(layer);
|
||||
missingTranslations.push(...validateTranslationCompletenessOfObject(layerConfig, themeFile.language, "Layer " + layer))
|
||||
export default class LayerOverviewUtils {
|
||||
|
||||
getLayerFiles(): {parsed: LayerConfigJson, path: string}[] {
|
||||
return ScriptUtils.readDirRecSync("./assets/layers")
|
||||
.filter(path => path.indexOf(".json") > 0)
|
||||
.filter(path => path.indexOf("license_info.json") < 0)
|
||||
.map(path => {
|
||||
try {
|
||||
const parsed = JSON.parse(readFileSync(path, "UTF8"));
|
||||
return {parsed: parsed, path: path}
|
||||
} catch (e) {
|
||||
console.error("Could not parse file ", "./assets/layers/" + path, "due to ", e)
|
||||
}
|
||||
} else {
|
||||
if (layer.builtin !== undefined) {
|
||||
if (!knownLayerIds.has(layer.builtin)) {
|
||||
themeErrorCount.push("Unknown layer id: " + layer.builtin + "(which uses inheritance)")
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
getThemeFiles() {
|
||||
return ScriptUtils.readDirRecSync("./assets/themes")
|
||||
.filter(path => path.endsWith(".json"))
|
||||
.filter(path => path.indexOf("license_info.json") < 0)
|
||||
.map(path => {
|
||||
try {
|
||||
return JSON.parse(readFileSync(path, "UTF8"));
|
||||
} catch (e) {
|
||||
console.error("Could not read file ", path, "due to ", e)
|
||||
throw e
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
loadThemesAndLayers(): LayersAndThemes {
|
||||
|
||||
const layerFiles = this.getLayerFiles();
|
||||
|
||||
const themeFiles: any[] = this.getThemeFiles();
|
||||
|
||||
console.log("Discovered", layerFiles.length, "layers and", themeFiles.length, "themes\n")
|
||||
return {
|
||||
layers: layerFiles,
|
||||
themes: themeFiles
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
writeFiles(lt: LayersAndThemes) {
|
||||
writeFileSync("./assets/generated/known_layers_and_themes.json", JSON.stringify({
|
||||
"layers": lt.layers.map(l => l.parsed),
|
||||
"themes": lt.themes
|
||||
}))
|
||||
}
|
||||
|
||||
|
||||
validateLayer(layerJson: LayerConfigJson, path: string, knownPaths: Set<string>, context?: string): string[] {
|
||||
let errorCount = [];
|
||||
if (layerJson["overpassTags"] !== undefined) {
|
||||
errorCount.push("Layer " + layerJson.id + "still uses the old 'overpassTags'-format. Please use \"source\": {\"osmTags\": <tags>}' instead of \"overpassTags\": <tags> (note: this isn't your fault, the custom theme generator still spits out the old format)")
|
||||
}
|
||||
try {
|
||||
const layer = new LayerConfig(layerJson, "test", true)
|
||||
const images = Array.from(layer.ExtractImages())
|
||||
const remoteImages = images.filter(img => img.indexOf("http") == 0)
|
||||
for (const remoteImage of remoteImages) {
|
||||
errorCount.push("Found a remote image: " + remoteImage + " in layer " + layer.id + ", please download it. You can use the fixTheme script to automate this")
|
||||
}
|
||||
const expected: string = `assets/layers/${layer.id}/${layer.id}.json`
|
||||
if (path != undefined && path.indexOf(expected) < 0) {
|
||||
errorCount.push("Layer is in an incorrect place. The path is " + path + ", but expected " + expected)
|
||||
}
|
||||
|
||||
for (const image of images) {
|
||||
if (image.indexOf("{") >= 0) {
|
||||
console.warn("Ignoring image with { in the path: ", image)
|
||||
continue
|
||||
}
|
||||
|
||||
if (!knownPaths.has(image)) {
|
||||
const ctx = context === undefined ? "" : ` in a layer defined in the theme ${context}`
|
||||
errorCount.push(`Image with path ${image} not found or not attributed; it is used in ${layer.id}${ctx}`)
|
||||
}
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
return [`Layer ${layerJson.id}` ?? JSON.stringify(layerJson).substring(0, 50) + " is invalid: " + e]
|
||||
}
|
||||
return errorCount
|
||||
}
|
||||
|
||||
validateTranslationCompletenessOfObject(object: any, expectedLanguages: string[], context: string) {
|
||||
const missingTranlations = []
|
||||
const translations: { tr: Translation, context: string }[] = [];
|
||||
const queue: { object: any, context: string }[] = [{object: object, context: context}]
|
||||
|
||||
while (queue.length > 0) {
|
||||
const item = queue.pop();
|
||||
const o = item.object
|
||||
for (const key in o) {
|
||||
const v = o[key];
|
||||
if (v === undefined) {
|
||||
continue;
|
||||
}
|
||||
if (v instanceof Translation || v?.translations !== undefined) {
|
||||
translations.push({tr: v, context: item.context});
|
||||
} else if (
|
||||
["string", "function", "boolean", "number"].indexOf(typeof (v)) < 0) {
|
||||
queue.push({object: v, context: item.context + "." + key})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const missing = {}
|
||||
const present = {}
|
||||
for (const ln of expectedLanguages) {
|
||||
missing[ln] = 0;
|
||||
present[ln] = 0;
|
||||
for (const translation of translations) {
|
||||
if (translation.tr.translations["*"] !== undefined) {
|
||||
continue;
|
||||
}
|
||||
const txt = translation.tr.translations[ln];
|
||||
const isMissing = txt === undefined || txt === "" || txt.toLowerCase().indexOf("todo") >= 0;
|
||||
if (isMissing) {
|
||||
missingTranlations.push(`${translation.context},${ln},${translation.tr.txt}`)
|
||||
missing[ln]++
|
||||
} else {
|
||||
present[ln]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let message = `Translation completeness for ${context}`
|
||||
let isComplete = true;
|
||||
for (const ln of expectedLanguages) {
|
||||
const amiss = missing[ln];
|
||||
const ok = present[ln];
|
||||
const total = amiss + ok;
|
||||
message += ` ${ln}: ${ok}/${total}`
|
||||
if (ok !== total) {
|
||||
isComplete = false;
|
||||
}
|
||||
}
|
||||
return missingTranlations
|
||||
|
||||
}
|
||||
|
||||
main(args: string[]) {
|
||||
|
||||
const lt = this.loadThemesAndLayers();
|
||||
const layerFiles = lt.layers;
|
||||
const themeFiles = lt.themes;
|
||||
|
||||
console.log(" ---------- VALIDATING ---------")
|
||||
const licensePaths = []
|
||||
for (const i in licenses) {
|
||||
licensePaths.push(licenses[i].path)
|
||||
}
|
||||
const knownPaths = new Set<string>(licensePaths)
|
||||
|
||||
let layerErrorCount = []
|
||||
const knownLayerIds = new Map<string, LayerConfig>();
|
||||
for (const layerFile of layerFiles) {
|
||||
|
||||
layerErrorCount.push(...this.validateLayer(layerFile.parsed, layerFile.path, knownPaths))
|
||||
knownLayerIds.set(layerFile.parsed.id, new LayerConfig(layerFile.parsed))
|
||||
}
|
||||
|
||||
let themeErrorCount = []
|
||||
let missingTranslations = []
|
||||
for (const themeFile of themeFiles) {
|
||||
if (typeof themeFile.language === "string") {
|
||||
themeErrorCount.push("The theme " + themeFile.id + " has a string as language. Please use a list of strings")
|
||||
}
|
||||
for (const layer of themeFile.layers) {
|
||||
if (typeof layer === "string") {
|
||||
if (!knownLayerIds.has(layer)) {
|
||||
themeErrorCount.push(`Unknown layer id: ${layer} in theme ${themeFile.id}`)
|
||||
} else {
|
||||
const layerConfig = knownLayerIds.get(layer);
|
||||
missingTranslations.push(...this.validateTranslationCompletenessOfObject(layerConfig, themeFile.language, "Layer " + layer))
|
||||
|
||||
}
|
||||
} else {
|
||||
// layer.builtin contains layer overrides - we can skip those
|
||||
layerErrorCount.push(...validateLayer(layer, undefined, knownPaths, themeFile.id))
|
||||
if (layer.builtin !== undefined) {
|
||||
if (!knownLayerIds.has(layer.builtin)) {
|
||||
themeErrorCount.push("Unknown layer id: " + layer.builtin + "(which uses inheritance)")
|
||||
}
|
||||
} else {
|
||||
// layer.builtin contains layer overrides - we can skip those
|
||||
layerErrorCount.push(...this.validateLayer(layer, undefined, knownPaths, themeFile.id))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
themeFile.layers = themeFile.layers
|
||||
.filter(l => typeof l != "string") // We remove all the builtin layer references as they don't work with ts-node for some weird reason
|
||||
.filter(l => l.builtin === undefined)
|
||||
themeFile.layers = themeFile.layers
|
||||
.filter(l => typeof l != "string") // We remove all the builtin layer references as they don't work with ts-node for some weird reason
|
||||
.filter(l => l.builtin === undefined)
|
||||
|
||||
missingTranslations.push(...validateTranslationCompletenessOfObject(themeFile, themeFile.language, "Theme " + themeFile.id))
|
||||
missingTranslations.push(...this.validateTranslationCompletenessOfObject(themeFile, themeFile.language, "Theme " + themeFile.id))
|
||||
|
||||
try {
|
||||
const theme = new LayoutConfig(themeFile, true, "test")
|
||||
if (theme.id !== theme.id.toLowerCase()) {
|
||||
themeErrorCount.push("Theme ids should be in lowercase, but it is " + theme.id)
|
||||
try {
|
||||
const theme = new LayoutConfig(themeFile, true, "test")
|
||||
if (theme.id !== theme.id.toLowerCase()) {
|
||||
themeErrorCount.push("Theme ids should be in lowercase, but it is " + theme.id)
|
||||
}
|
||||
} catch (e) {
|
||||
themeErrorCount.push("Could not parse theme " + themeFile["id"] + "due to", e)
|
||||
}
|
||||
} catch (e) {
|
||||
themeErrorCount.push("Could not parse theme " + themeFile["id"] + "due to", e)
|
||||
}
|
||||
}
|
||||
|
||||
if(missingTranslations.length > 0){
|
||||
console.log(missingTranslations.length, "missing translations")
|
||||
writeFileSync("missing_translations.txt", missingTranslations.join("\n"))
|
||||
}
|
||||
|
||||
if (layerErrorCount.length + themeErrorCount.length == 0) {
|
||||
console.log("All good!")
|
||||
|
||||
// We load again from disc, as modifications were made above
|
||||
const lt = loadThemesAndLayers();
|
||||
writeFiles(lt);
|
||||
} else {
|
||||
const errors = layerErrorCount.concat(themeErrorCount).join("\n")
|
||||
console.log(errors)
|
||||
const msg = (`Found ${layerErrorCount.length} errors in the layers; ${themeErrorCount.length} errors in the themes`)
|
||||
console.log(msg)
|
||||
if (process.argv.indexOf("--report") >= 0) {
|
||||
console.log("Writing report!")
|
||||
writeFileSync("layer_report.txt", errors)
|
||||
}
|
||||
|
||||
if (process.argv.indexOf("--no-fail") < 0) {
|
||||
throw msg;
|
||||
if (missingTranslations.length > 0) {
|
||||
console.log(missingTranslations.length, "missing translations")
|
||||
writeFileSync("missing_translations.txt", missingTranslations.join("\n"))
|
||||
}
|
||||
|
||||
if (layerErrorCount.length + themeErrorCount.length == 0) {
|
||||
console.log("All good!")
|
||||
|
||||
// We load again from disc, as modifications were made above
|
||||
const lt = this.loadThemesAndLayers();
|
||||
this.writeFiles(lt);
|
||||
} else {
|
||||
const errors = layerErrorCount.concat(themeErrorCount).join("\n")
|
||||
console.log(errors)
|
||||
const msg = (`Found ${layerErrorCount.length} errors in the layers; ${themeErrorCount.length} errors in the themes`)
|
||||
console.log(msg)
|
||||
if (process.argv.indexOf("--report") >= 0) {
|
||||
console.log("Writing report!")
|
||||
writeFileSync("layer_report.txt", errors)
|
||||
}
|
||||
|
||||
if (process.argv.indexOf("--no-fail") < 0) {
|
||||
throw msg;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main(process.argv)
|
||||
new LayerOverviewUtils().main(process.argv)
|
|
@ -2,40 +2,130 @@ import * as fs from "fs";
|
|||
import {Utils} from "../Utils";
|
||||
import ScriptUtils from "./ScriptUtils";
|
||||
import {readFileSync, writeFileSync} from "fs";
|
||||
import LayerConfig from "../Customizations/JSON/LayerConfig";
|
||||
import {LayerConfigJson} from "../Customizations/JSON/LayerConfigJson";
|
||||
import * as bookcases from "../assets/layers/public_bookcase/public_bookcase.json"
|
||||
import LayerOverviewUtils from "./generateLayerOverview";
|
||||
|
||||
const knownLanguages = ["en", "nl", "de", "fr", "es", "gl", "ca"];
|
||||
|
||||
class TranslationPart {
|
||||
|
||||
contents: Map<string, TranslationPart | string> = new Map<string, TranslationPart | string>()
|
||||
|
||||
add(language: string, obj: any){
|
||||
add(language: string, obj: any) {
|
||||
for (const key in obj) {
|
||||
const v = obj[key]
|
||||
if(!this.contents.has(key)){
|
||||
if (!this.contents.has(key)) {
|
||||
this.contents.set(key, new TranslationPart())
|
||||
}
|
||||
const subpart = this.contents.get(key) as TranslationPart
|
||||
|
||||
if(typeof v === "string"){
|
||||
if (typeof v === "string") {
|
||||
subpart.contents.set(language, v)
|
||||
}else{
|
||||
} else {
|
||||
subpart.add(language, v)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
toJson(): string{
|
||||
const parts = []
|
||||
for (let key of Array.from(this.contents.keys()) ){
|
||||
const value = this.contents.get(key);
|
||||
addTranslationObject(translations: any, context?: string) {
|
||||
for (const translationsKey in translations) {
|
||||
if (!translations.hasOwnProperty(translationsKey)) {
|
||||
continue;
|
||||
}
|
||||
const v = translations[translationsKey]
|
||||
if (typeof (v) != "string") {
|
||||
console.error("Non-string object in translation: ", translations[translationsKey])
|
||||
throw "Error in an object depicting a translation: a non-string object was found. (" + context + ")\n You probably put some other section accidentally in the translation"
|
||||
}
|
||||
this.contents.set(translationsKey, v)
|
||||
}
|
||||
}
|
||||
|
||||
if(typeof value === "string"){
|
||||
parts.push(`\"${key}\": \"${value}\"`)
|
||||
}else{
|
||||
parts.push(`\"${key}\": ${(value as TranslationPart).toJson()}`);
|
||||
isLeaf() {
|
||||
for (let key of Array.from(this.contents.keys())) {
|
||||
const value = this.contents.get(key);
|
||||
if (typeof value !== "string") {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return JSON.stringify(JSON.parse(`{${parts.join(",")}}`), null, " ");
|
||||
return true;
|
||||
}
|
||||
|
||||
recursiveAdd(object: any) {
|
||||
|
||||
|
||||
const isProbablyTranslationObject = knownLanguages.map(l => object.hasOwnProperty(l)).filter(x => x).length > 0;
|
||||
if (isProbablyTranslationObject) {
|
||||
this.addTranslationObject(object)
|
||||
return;
|
||||
}
|
||||
|
||||
for (const key in object) {
|
||||
if (!object.hasOwnProperty(key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const v = object[key]
|
||||
if (v == null) {
|
||||
console.warn("Got a null value for key ", key)
|
||||
continue
|
||||
}
|
||||
|
||||
if (typeof v !== "object") {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!this.contents.get(key)) {
|
||||
this.contents.set(key, new TranslationPart())
|
||||
}
|
||||
|
||||
(this.contents.get(key) as TranslationPart).recursiveAdd(v);
|
||||
}
|
||||
}
|
||||
|
||||
knownLanguages(): string[] {
|
||||
const languages = []
|
||||
for (let key of Array.from(this.contents.keys())) {
|
||||
const value = this.contents.get(key);
|
||||
|
||||
if (typeof value === "string") {
|
||||
languages.push(key)
|
||||
} else {
|
||||
languages.push(...(value as TranslationPart).knownLanguages())
|
||||
}
|
||||
}
|
||||
return Utils.Dedup(languages);
|
||||
}
|
||||
|
||||
toJson(neededLanguage?: string): string {
|
||||
const parts = []
|
||||
|
||||
for (let key of Array.from(this.contents.keys())) {
|
||||
let value = this.contents.get(key);
|
||||
|
||||
if (typeof value === "string") {
|
||||
value = value.replace(/"/g, "\\\"")
|
||||
if(neededLanguage === undefined){
|
||||
parts.push(`\"${key}\": \"${value}\"`)
|
||||
}else if (key === neededLanguage){
|
||||
return `"${value}"`
|
||||
}
|
||||
|
||||
} else {
|
||||
const sub = (value as TranslationPart).toJson(neededLanguage)
|
||||
if (sub !== "") {
|
||||
parts.push(`\"${key}\": ${sub}`);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
if (parts.length === 0) {
|
||||
return "";
|
||||
}
|
||||
return `{${parts.join(",")}}`;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -57,11 +147,11 @@ function transformTranslation(obj: any, depth = 1) {
|
|||
|
||||
let values = ""
|
||||
for (const key in obj) {
|
||||
if(key === "#"){
|
||||
if (key === "#") {
|
||||
continue;
|
||||
}
|
||||
if(key.match("^[a-zA-Z0-9_]*$") === null){
|
||||
throw "Invalid character in key: "+key
|
||||
if (key.match("^[a-zA-Z0-9_]*$") === null) {
|
||||
throw "Invalid character in key: " + key
|
||||
}
|
||||
values += (Utils.Times((_) => " ", depth)) + key + ": " + transformTranslation(obj[key], depth + 1) + ",\n"
|
||||
}
|
||||
|
@ -83,7 +173,7 @@ function genTranslations() {
|
|||
}
|
||||
|
||||
// Read 'lang/*.json', writes to 'assets/generated/translations.json'
|
||||
function compileTranslationsFromWeblate(){
|
||||
function compileTranslationsFromWeblate() {
|
||||
const translations = ScriptUtils.readDirRecSync("./langs")
|
||||
.filter(path => path.indexOf(".json") > 0)
|
||||
|
||||
|
@ -92,13 +182,48 @@ function compileTranslationsFromWeblate(){
|
|||
for (const translationFile of translations) {
|
||||
const contents = JSON.parse(readFileSync(translationFile, "utf-8"));
|
||||
let language = translationFile.substring(translationFile.lastIndexOf("/") + 1)
|
||||
language = language.substring(0, language.length-5)
|
||||
language = language.substring(0, language.length - 5)
|
||||
allTranslations.add(language, contents)
|
||||
}
|
||||
|
||||
writeFileSync("./assets/generated/translations.json", allTranslations.toJson())
|
||||
writeFileSync("./assets/generated/translations.json", JSON.stringify(JSON.parse(allTranslations.toJson()), null, " "))
|
||||
|
||||
}
|
||||
|
||||
function generateTranslationFromLayerConfig(layerConfig: LayerConfigJson): TranslationPart {
|
||||
const tr = new TranslationPart();
|
||||
tr.recursiveAdd(layerConfig)
|
||||
return tr;
|
||||
}
|
||||
|
||||
function generateLayerTranslationsObject() {
|
||||
const layerFiles = new LayerOverviewUtils().getLayerFiles();
|
||||
|
||||
const tr = new TranslationPart();
|
||||
|
||||
for (const layerFile of layerFiles) {
|
||||
const config: LayerConfigJson = layerFile.parsed;
|
||||
const layerTr = generateTranslationFromLayerConfig(config)
|
||||
tr.contents.set(config.id, layerTr)
|
||||
}
|
||||
|
||||
const langs = tr.knownLanguages();
|
||||
for (const lang of langs) {
|
||||
console.log("Exporting ", lang)
|
||||
|
||||
let json = tr.toJson(lang)
|
||||
try{
|
||||
json = JSON.stringify(JSON.parse(json), null, " ");
|
||||
}catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
|
||||
writeFileSync("langs/layers/" + lang + ".json", json)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
generateLayerTranslationsObject()
|
||||
|
||||
compileTranslationsFromWeblate();
|
||||
genTranslations()
|
Loading…
Reference in a new issue