diff --git a/Logic/Actors/GeoLocationHandler.ts b/Logic/Actors/GeoLocationHandler.ts index e86c1baa7..f8e38f50c 100644 --- a/Logic/Actors/GeoLocationHandler.ts +++ b/Logic/Actors/GeoLocationHandler.ts @@ -1,244 +1,262 @@ import * as L from "leaflet"; -import {UIEventSource} from "../UIEventSource"; -import {Utils} from "../../Utils"; +import { UIEventSource } from "../UIEventSource"; +import { Utils } from "../../Utils"; import Svg from "../../Svg"; import Img from "../../UI/Base/Img"; -import {LocalStorageSource} from "../Web/LocalStorageSource"; +import { LocalStorageSource } from "../Web/LocalStorageSource"; import LayoutConfig from "../../Customizations/JSON/LayoutConfig"; -import {VariableUiElement} from "../../UI/Base/VariableUIElement"; +import { VariableUiElement } from "../../UI/Base/VariableUIElement"; export default class GeoLocationHandler extends VariableUiElement { + /** + * Wether or not the geolocation is active, aka the user requested the current location + * @private + */ + private readonly _isActive: UIEventSource; - /** - * Wether or not the geolocation is active, aka the user requested the current location - * @private - */ - private readonly _isActive: UIEventSource; + /** + * Wether or not the geolocation is locked, aka the user requested the current location and wants the crosshair to follow the user + * @private + */ + private readonly _isLocked: UIEventSource; - /** - * The callback over the permission API - * @private - */ - private readonly _permission: UIEventSource; - /*** - * The marker on the map, in order to update it - * @private - */ - private _marker: L.Marker; - /** - * Literally: _currentGPSLocation.data != undefined - * @private - */ - private readonly _hasLocation: UIEventSource; - private readonly _currentGPSLocation: UIEventSource<{ latlng: any; accuracy: number }>; - /** - * Kept in order to update the marker - * @private - */ - private readonly _leafletMap: UIEventSource; - /** - * The date when the user requested the geolocation. If we have a location, it'll autozoom to it the first 30 secs - * @private - */ - private _lastUserRequest: Date; - /** - * A small flag on localstorage. If the user previously granted the geolocation, it will be set. - * On firefox, the permissions api is broken (probably fingerprint resistiance) and "granted + don't ask again" doesn't stick between sessions. - * - * Instead, we set this flag. If this flag is set upon loading the page, we start geolocating immediately. - * If the user denies the geolocation this time, we unset this flag - * @private - */ - private readonly _previousLocationGrant: UIEventSource; - private readonly _layoutToUse: UIEventSource; + /** + * The callback over the permission API + * @private + */ + private readonly _permission: UIEventSource; + /*** + * The marker on the map, in order to update it + * @private + */ + private _marker: L.Marker; + /** + * Literally: _currentGPSLocation.data != undefined + * @private + */ + private readonly _hasLocation: UIEventSource; + private readonly _currentGPSLocation: UIEventSource<{ + latlng: any; + accuracy: number; + }>; + /** + * Kept in order to update the marker + * @private + */ + private readonly _leafletMap: UIEventSource; + /** + * The date when the user requested the geolocation. If we have a location, it'll autozoom to it the first 30 secs + * @private + */ + private _lastUserRequest: Date; + /** + * A small flag on localstorage. If the user previously granted the geolocation, it will be set. + * On firefox, the permissions api is broken (probably fingerprint resistiance) and "granted + don't ask again" doesn't stick between sessions. + * + * Instead, we set this flag. If this flag is set upon loading the page, we start geolocating immediately. + * If the user denies the geolocation this time, we unset this flag + * @private + */ + private readonly _previousLocationGrant: UIEventSource; + private readonly _layoutToUse: UIEventSource; + constructor( + currentGPSLocation: UIEventSource<{ latlng: any; accuracy: number }>, + leafletMap: UIEventSource, + layoutToUse: UIEventSource + ) { + const hasLocation = currentGPSLocation.map( + (location) => location !== undefined + ); + const previousLocationGrant = LocalStorageSource.Get( + "geolocation-permissions" + ); + const isActive = new UIEventSource(false); + const isLocked = new UIEventSource(false); - constructor(currentGPSLocation: UIEventSource<{ latlng: any; accuracy: number }>, - leafletMap: UIEventSource, - layoutToUse: UIEventSource) { + super( + hasLocation.map( + (hasLocationData) => { + if (isLocked.data) { + return Svg.up_ui(); + } else if (hasLocationData) { + return Svg.crosshair_blue_ui(); + } else if (isActive.data) { + return Svg.crosshair_blue_center_ui(); + } else { + return Svg.crosshair_ui(); + } + }, + [isActive, isLocked] + ) + ); + this._isActive = isActive; + this._isLocked = isLocked; + this._permission = new UIEventSource(""); + this._previousLocationGrant = previousLocationGrant; + this._currentGPSLocation = currentGPSLocation; + this._leafletMap = leafletMap; + this._layoutToUse = layoutToUse; + this._hasLocation = hasLocation; + const self = this; - const hasLocation = currentGPSLocation.map((location) => location !== undefined); - const previousLocationGrant = LocalStorageSource.Get("geolocation-permissions") - const isActive = new UIEventSource(false); + const currentPointer = this._isActive.map( + (isActive) => { + if (isActive && !self._hasLocation.data) { + return "cursor-wait"; + } + return "cursor-pointer"; + }, + [this._hasLocation] + ); + currentPointer.addCallbackAndRun((pointerClass) => { + self.SetClass(pointerClass); + }); - super( - hasLocation.map(hasLocation => { + this.onClick(() => { + self.init(true); + if (self._isActive.data) { + self._isLocked.setData(!self._isLocked.data); + } + }); + this.init(false); - if (hasLocation) { - return Svg.crosshair_blue_ui() - } - if (isActive.data) { - return Svg.crosshair_blue_center_ui(); - } - return Svg.crosshair_ui(); - }, [isActive]) + this._currentGPSLocation.addCallback((location) => { + self._previousLocationGrant.setData("granted"); + + const timeSinceRequest = + (new Date().getTime() - (self._lastUserRequest?.getTime() ?? 0)) / 1000; + if (timeSinceRequest < 30) { + self.MoveToCurrentLoction(16); + } else if (self._isLocked.data) { + self.MoveToCurrentLoction(); + } + + let color = "#1111cc"; + try { + color = getComputedStyle(document.body).getPropertyValue( + "--catch-detail-color" ); - this._isActive = isActive; - this._permission = new UIEventSource("") - this._previousLocationGrant = previousLocationGrant; - this._currentGPSLocation = currentGPSLocation; - this._leafletMap = leafletMap; - this._layoutToUse = layoutToUse; - this._hasLocation = hasLocation; - const self = this; + } catch (e) { + console.error(e); + } + const icon = L.icon({ + iconUrl: Img.AsData(Svg.crosshair.replace(/#000000/g, color)), + iconSize: [40, 40], // size of the icon + iconAnchor: [20, 20], // point of the icon which will correspond to marker's location + }); - const currentPointer = this._isActive.map(isActive => { - if (isActive && !self._hasLocation.data) { - return "cursor-wait" - } - return "cursor-pointer" - }, [this._hasLocation]) - currentPointer.addCallbackAndRun(pointerClass => { - self.SetClass(pointerClass); - }) + const map = self._leafletMap.data; + const newMarker = L.marker(location.latlng, { icon: icon }); + newMarker.addTo(map); - this.onClick(() => self.init(true)) - this.init(false) + if (self._marker !== undefined) { + map.removeLayer(self._marker); + } + self._marker = newMarker; + }); + } + private init(askPermission: boolean) { + const self = this; + + if (self._isActive.data) { + self.MoveToCurrentLoction(16); + return; } - private init(askPermission: boolean) { - - const self = this; - const map = this._leafletMap.data; - - this._currentGPSLocation.addCallback((location) => { - self._previousLocationGrant.setData("granted"); - - const timeSinceRequest = (new Date().getTime() - (self._lastUserRequest?.getTime() ?? 0)) / 1000; - if (timeSinceRequest < 30) { - self.MoveToCurrentLoction(16) - } - - let color = "#1111cc"; - try { - color = getComputedStyle(document.body).getPropertyValue("--catch-detail-color") - } catch (e) { - console.error(e) - } - const icon = L.icon( - { - iconUrl: Img.AsData(Svg.crosshair.replace(/#000000/g, color)), - iconSize: [40, 40], // size of the icon - iconAnchor: [20, 20], // point of the icon which will correspond to marker's location - }) - - const newMarker = L.marker(location.latlng, {icon: icon}); - newMarker.addTo(map); - - if (self._marker !== undefined) { - map.removeLayer(self._marker); - } - self._marker = newMarker; - }); - - try { - - navigator?.permissions?.query({name: 'geolocation'}) - ?.then(function (status) { - console.log("Geolocation is already", status) - if (status.state === "granted") { - self.StartGeolocating(false); - } - self._permission.setData(status.state); - status.onchange = function () { - self._permission.setData(status.state); - } - }); - - } catch (e) { - console.error(e) - } - if (askPermission) { - self.StartGeolocating(true); - } else if (this._previousLocationGrant.data === "granted") { - this._previousLocationGrant.setData(""); + try { + navigator?.permissions + ?.query({ name: "geolocation" }) + ?.then(function (status) { + console.log("Geolocation is already", status); + if (status.state === "granted") { self.StartGeolocating(false); - } - + } + self._permission.setData(status.state); + status.onchange = function () { + self._permission.setData(status.state); + }; + }); + } catch (e) { + console.error(e); } - private locate() { - const self = this; - const map: any = this._leafletMap.data; + if (askPermission) { + self.StartGeolocating(true); + } else if (this._previousLocationGrant.data === "granted") { + this._previousLocationGrant.setData(""); + self.StartGeolocating(false); + } + } - if (navigator.geolocation) { - navigator.geolocation.getCurrentPosition(function (position) { - self._currentGPSLocation.setData({ - latlng: [position.coords.latitude, position.coords.longitude], - accuracy: position.coords.accuracy - }); - }, function () { - console.warn("Could not get location with navigator.geolocation") - }); - return; - } else { - map.findAccuratePosition({ - maxWait: 10000, // defaults to 10000 - desiredAccuracy: 50 // defaults to 20 - }); - } + private MoveToCurrentLoction(targetZoom?: number) { + const location = this._currentGPSLocation.data; + this._lastUserRequest = undefined; + + if ( + this._currentGPSLocation.data.latlng[0] === 0 && + this._currentGPSLocation.data.latlng[1] === 0 + ) { + console.debug("Not moving to GPS-location: it is null island"); + return; } - private MoveToCurrentLoction(targetZoom = 16) { - const location = this._currentGPSLocation.data; - this._lastUserRequest = undefined; + // We check that the GPS location is not out of bounds + const b = this._layoutToUse.data.lockLocation; + let inRange = true; + if (b) { + if (b !== true) { + // B is an array with our locklocation + inRange = + b[0][0] <= location.latlng[0] && + location.latlng[0] <= b[1][0] && + b[0][1] <= location.latlng[1] && + location.latlng[1] <= b[1][1]; + } + } + if (!inRange) { + console.log( + "Not zooming to GPS location: out of bounds", + b, + location.latlng + ); + } else { + this._leafletMap.data.setView(location.latlng, targetZoom); + } + } + private StartGeolocating(zoomToGPS = true) { + const self = this; + console.log("Starting geolocation"); - if (this._currentGPSLocation.data.latlng[0] === 0 && this._currentGPSLocation.data.latlng[1] === 0) { - console.debug("Not moving to GPS-location: it is null island") - return; - } - - // We check that the GPS location is not out of bounds - const b = this._layoutToUse.data.lockLocation - let inRange = true; - if (b) { - if (b !== true) { - // B is an array with our locklocation - inRange = b[0][0] <= location.latlng[0] && location.latlng[0] <= b[1][0] && - b[0][1] <= location.latlng[1] && location.latlng[1] <= b[1][1]; - } - } - if (!inRange) { - console.log("Not zooming to GPS location: out of bounds", b, location.latlng) - } else { - this._leafletMap.data.setView( - location.latlng, targetZoom - ); - } + this._lastUserRequest = zoomToGPS ? new Date() : new Date(0); + if (self._permission.data === "denied") { + self._previousLocationGrant.setData(""); + return ""; + } + if (this._currentGPSLocation.data !== undefined) { + this.MoveToCurrentLoction(16); } - private StartGeolocating(zoomToGPS = true) { - const self = this; - console.log("Starting geolocation") + console.log("Searching location using GPS"); - this._lastUserRequest = zoomToGPS ? new Date() : new Date(0); - if (self._permission.data === "denied") { - self._previousLocationGrant.setData(""); - return ""; - } - if (this._currentGPSLocation.data !== undefined) { - this.MoveToCurrentLoction(16) - } - - - console.log("Searching location using GPS") - this.locate(); - - - if (!self._isActive.data) { - self._isActive.setData(true); - Utils.DoEvery(60000, () => { - - if (document.visibilityState !== "visible") { - console.log("Not starting gps: document not visible") - return; - } - this.locate(); - }) - } + if (self._isActive.data) { + return; } + self._isActive.setData(true); -} \ No newline at end of file + navigator.geolocation.watchPosition( + function (position) { + self._currentGPSLocation.setData({ + latlng: [position.coords.latitude, position.coords.longitude], + accuracy: position.coords.accuracy, + }); + }, + function () { + console.warn("Could not get location with navigator.geolocation"); + } + ); + } +} diff --git a/assets/layers/picnic_table/picnic_table.json b/assets/layers/picnic_table/picnic_table.json index e5be9d077..672e41f07 100644 --- a/assets/layers/picnic_table/picnic_table.json +++ b/assets/layers/picnic_table/picnic_table.json @@ -26,7 +26,8 @@ "en": "The layer showing picnic tables", "nl": "Deze laag toont picnictafels", "it": "Il livello che mostra i tavoli da picnic", - "fr": "La couche montrant les tables de pique-nique" + "fr": "La couche montrant les tables de pique-nique", + "ru": "Слой, отображающий столы для пикника" }, "tagRenderings": [ { @@ -34,13 +35,15 @@ "en": "What material is this picnic table made of?", "nl": "Van welk materiaal is deze picnictafel gemaakt?", "it": "Di che materiale è fatto questo tavolo da picnic?", - "de": "Aus welchem Material besteht dieser Picknicktisch?" + "de": "Aus welchem Material besteht dieser Picknicktisch?", + "ru": "Из чего изготовлен этот стол для пикника?" }, "render": { "en": "This picnic table is made of {material}", "nl": "Deze picnictafel is gemaakt van {material}", "it": "Questo tavolo da picnic è fatto di {material}", - "de": "Dieser Picknicktisch besteht aus {material}" + "de": "Dieser Picknicktisch besteht aus {material}", + "ru": "Этот стол для пикника сделан из {material}" }, "freeform": { "key": "material" diff --git a/assets/layers/playground/playground.json b/assets/layers/playground/playground.json index 54afa9a4c..ec97eca2b 100644 --- a/assets/layers/playground/playground.json +++ b/assets/layers/playground/playground.json @@ -93,7 +93,8 @@ "nl": "De ondergrond bestaat uit houtsnippers", "en": "The surface consist of woodchips", "it": "La superficie consiste di trucioli di legno", - "de": "Die Oberfläche besteht aus Holzschnitzeln" + "de": "Die Oberfläche besteht aus Holzschnitzeln", + "ru": "Покрытие из щепы" } }, { @@ -154,7 +155,8 @@ "en": "Is this playground lit at night?", "it": "È illuminato di notte questo parco giochi?", "fr": "Ce terrain de jeux est-il éclairé la nuit ?", - "de": "Ist dieser Spielplatz nachts beleuchtet?" + "de": "Ist dieser Spielplatz nachts beleuchtet?", + "ru": "Эта игровая площадка освещается ночью?" }, "mappings": [ { @@ -163,7 +165,8 @@ "nl": "Deze speeltuin is 's nachts verlicht", "en": "This playground is lit at night", "it": "Questo parco giochi è illuminato di notte", - "de": "Dieser Spielplatz ist nachts beleuchtet" + "de": "Dieser Spielplatz ist nachts beleuchtet", + "ru": "Эта детская площадка освещается ночью" } }, { @@ -172,7 +175,8 @@ "nl": "Deze speeltuin is 's nachts niet verlicht", "en": "This playground is not lit at night", "it": "Questo parco giochi non è illuminato di notte", - "de": "Dieser Spielplatz ist nachts nicht beleuchtet" + "de": "Dieser Spielplatz ist nachts nicht beleuchtet", + "ru": "Эта детская площадка не освещается ночью" } } ] @@ -189,7 +193,8 @@ "nl": "Wat is de minimale leeftijd om op deze speeltuin te mogen?", "en": "What is the minimum age required to access this playground?", "it": "Qual è l’età minima per accedere a questo parco giochi?", - "fr": "Quel est l'âge minimal requis pour accéder à ce terrain de jeux ?" + "fr": "Quel est l'âge minimal requis pour accéder à ce terrain de jeux ?", + "ru": "С какого возраста доступна эта детская площадка?" }, "freeform": { "key": "min_age", @@ -201,7 +206,8 @@ "nl": "Toegankelijk tot {max_age}", "en": "Accessible to kids of at most {max_age}", "it": "Accessibile ai bambini di età inferiore a {max_age}", - "fr": "Accessible aux enfants de {max_age} au maximum" + "fr": "Accessible aux enfants de {max_age} au maximum", + "ru": "Доступно детям до {max_age}" }, "question": { "nl": "Wat is de maximaal toegestane leeftijd voor deze speeltuin?", @@ -340,7 +346,8 @@ "en": "Is this playground accessible to wheelchair users?", "fr": "Ce terrain de jeux est-il accessible aux personnes en fauteuil roulant ?", "de": "Ist dieser Spielplatz für Rollstuhlfahrer zugänglich?", - "it": "Il campetto è accessibile a persone in sedia a rotelle?" + "it": "Il campetto è accessibile a persone in sedia a rotelle?", + "ru": "Доступна ли детская площадка пользователям кресел-колясок?" }, "mappings": [ { @@ -350,7 +357,8 @@ "en": "Completely accessible for wheelchair users", "fr": "Entièrement accessible aux personnes en fauteuil roulant", "de": "Vollständig zugänglich für Rollstuhlfahrer", - "it": "Completamente accessibile in sedia a rotelle" + "it": "Completamente accessibile in sedia a rotelle", + "ru": "Полностью доступна пользователям кресел-колясок" } }, { @@ -360,7 +368,8 @@ "en": "Limited accessibility for wheelchair users", "fr": "Accessibilité limitée pour les personnes en fauteuil roulant", "de": "Eingeschränkte Zugänglichkeit für Rollstuhlfahrer", - "it": "Accesso limitato in sedia a rotelle" + "it": "Accesso limitato in sedia a rotelle", + "ru": "Частично доступна пользователям кресел-колясок" } }, { @@ -370,7 +379,8 @@ "en": "Not accessible for wheelchair users", "fr": "Non accessible aux personnes en fauteuil roulant", "de": "Nicht zugänglich für Rollstuhlfahrer", - "it": "Non accessibile in sedia a rotelle" + "it": "Non accessibile in sedia a rotelle", + "ru": "Недоступна пользователям кресел-колясок" } } ] @@ -385,7 +395,8 @@ "nl": "Op welke uren is deze speeltuin toegankelijk?", "en": "When is this playground accessible?", "fr": "Quand ce terrain de jeux est-il accessible ?", - "it": "Quando si può accedere a questo campetto?" + "it": "Quando si può accedere a questo campetto?", + "ru": "Когда открыта эта игровая площадка?" }, "mappings": [ { @@ -394,7 +405,8 @@ "nl": "Van zonsopgang tot zonsondergang", "en": "Accessible from sunrise till sunset", "fr": "Accessible du lever au coucher du soleil", - "it": "Si può accedere dall'alba al tramonto" + "it": "Si può accedere dall'alba al tramonto", + "ru": "Открыто от рассвета до заката" } }, { diff --git a/assets/layers/public_bookcase/public_bookcase.json b/assets/layers/public_bookcase/public_bookcase.json index 496b36ae1..fdb223d06 100644 --- a/assets/layers/public_bookcase/public_bookcase.json +++ b/assets/layers/public_bookcase/public_bookcase.json @@ -13,7 +13,8 @@ "nl": "Een straatkastje met boeken voor iedereen", "de": "Ein Bücherschrank am Straßenrand mit Büchern, für jedermann zugänglich", "fr": "Une armoire ou une boite contenant des livres en libre accès", - "it": "Una vetrinetta ai bordi della strada contenente libri, aperta al pubblico" + "it": "Una vetrinetta ai bordi della strada contenente libri, aperta al pubblico", + "ru": "Уличный шкаф с книгами, доступными для всех" }, "source": { "osmTags": "amenity=public_bookcase" @@ -94,7 +95,7 @@ "nl": "Wat is de naam van dit boekenuilkastje?", "de": "Wie heißt dieser öffentliche Bücherschrank?", "fr": "Quel est le nom de cette microbibliothèque ?", - "ru": "Как называется общественный книжный шкаф?", + "ru": "Как называется этот общественный книжный шкаф?", "it": "Come si chiama questa microbiblioteca pubblica?" }, "freeform": { @@ -125,7 +126,8 @@ "nl": "Er passen {capacity} boeken", "de": "{capacity} Bücher passen in diesen Bücherschrank", "fr": "{capacity} livres peuvent entrer dans cette microbibliothèque", - "it": "Questa microbiblioteca può contenere fino a {capacity} libri" + "it": "Questa microbiblioteca può contenere fino a {capacity} libri", + "ru": "{capacity} книг помещается в этот книжный шкаф" }, "question": { "en": "How many books fit into this public bookcase?", @@ -147,7 +149,8 @@ "nl": "Voor welke doelgroep zijn de meeste boeken in dit boekenruilkastje?", "de": "Welche Art von Büchern sind in diesem öffentlichen Bücherschrank zu finden?", "fr": "Quel type de livres peut-on dans cette microbibliothèque ?", - "it": "Che tipo di libri si possono trovare in questa microbiblioteca?" + "it": "Che tipo di libri si possono trovare in questa microbiblioteca?", + "ru": "Какие книги можно найти в этом общественном книжном шкафу?" }, "mappings": [ { @@ -179,7 +182,8 @@ "nl": "Boeken voor zowel kinderen als volwassenen", "de": "Sowohl Bücher für Kinder als auch für Erwachsene", "fr": "Livres pour enfants et adultes également", - "it": "Sia libri per l'infanzia, sia per l'età adulta" + "it": "Sia libri per l'infanzia, sia per l'età adulta", + "ru": "Книги и для детей, и для взрослых" } } ] @@ -232,7 +236,8 @@ "nl": "Is dit boekenruilkastje publiek toegankelijk?", "de": "Ist dieser öffentliche Bücherschrank frei zugänglich?", "fr": "Cette microbibliothèque est-elle librement accèssible ?", - "it": "Questa microbiblioteca è ad accesso libero?" + "it": "Questa microbiblioteca è ad accesso libero?", + "ru": "Имеется ли свободный доступ к этому общественному книжному шкафу?" }, "condition": "indoor=yes", "mappings": [ @@ -242,7 +247,8 @@ "nl": "Publiek toegankelijk", "de": "Öffentlich zugänglich", "fr": "Accèssible au public", - "it": "È ad accesso libero" + "it": "È ad accesso libero", + "ru": "Свободный доступ" }, "if": "access=yes" }, @@ -374,14 +380,16 @@ "nl": "Op welke dag werd dit boekenruilkastje geinstalleerd?", "de": "Wann wurde dieser öffentliche Bücherschrank installiert?", "fr": "Quand a été installée cette microbibliothèque ?", - "it": "Quando è stata inaugurata questa microbiblioteca?" + "it": "Quando è stata inaugurata questa microbiblioteca?", + "ru": "Когда был установлен этот общественный книжный шкаф?" }, "render": { "en": "Installed on {start_date}", "nl": "Geplaatst op {start_date}", "de": "Installiert am {start_date}", "fr": "Installée le {start_date}", - "it": "È stata inaugurata il {start_date}" + "it": "È stata inaugurata il {start_date}", + "ru": "Установлен {start_date}" }, "freeform": { "key": "start_date", @@ -402,7 +410,8 @@ "nl": "Is er een website over dit boekenruilkastje?", "de": "Gibt es eine Website mit weiteren Informationen über diesen öffentlichen Bücherschrank?", "fr": "Y a-t-il un site web avec plus d'informations sur cette microbibliothèque ?", - "it": "C'è un sito web con maggiori informazioni su questa microbiblioteca?" + "it": "C'è un sito web con maggiori informazioni su questa microbiblioteca?", + "ru": "Есть ли веб-сайт с более подробной информацией об этом общественном книжном шкафе?" }, "freeform": { "key": "website", diff --git a/assets/layers/sport_pitch/sport_pitch.json b/assets/layers/sport_pitch/sport_pitch.json index efb49a0b2..140e222b2 100644 --- a/assets/layers/sport_pitch/sport_pitch.json +++ b/assets/layers/sport_pitch/sport_pitch.json @@ -32,7 +32,8 @@ "nl": "Een sportterrein", "fr": "Un terrain de sport", "en": "A sport pitch", - "it": "Un campo sportivo" + "it": "Un campo sportivo", + "ru": "Спортивная площадка" }, "tagRenderings": [ "images", @@ -64,7 +65,8 @@ "nl": "Hier kan men basketbal spelen", "fr": "Ici, on joue au basketball", "en": "Basketball is played here", - "it": "Qui si gioca a basket" + "it": "Qui si gioca a basket", + "ru": "Здесь можно играть в баскетбол" } }, { @@ -77,7 +79,8 @@ "nl": "Hier kan men voetbal spelen", "fr": "Ici, on joue au football", "en": "Soccer is played here", - "it": "Qui si gioca a calcio" + "it": "Qui si gioca a calcio", + "ru": "Здесь можно играть в футбол" } }, { @@ -104,7 +107,8 @@ "nl": "Hier kan men tennis spelen", "fr": "Ici, on joue au tennis", "en": "Tennis is played here", - "it": "Qui si gioca a tennis" + "it": "Qui si gioca a tennis", + "ru": "Здесь можно играть в теннис" } }, { @@ -117,7 +121,8 @@ "nl": "Hier kan men korfbal spelen", "fr": "Ici, on joue au korfball", "en": "Korfball is played here", - "it": "Qui si gioca a korfball" + "it": "Qui si gioca a korfball", + "ru": "Здесь можно играть в корфбол" } }, { @@ -130,7 +135,8 @@ "nl": "Hier kan men basketbal beoefenen", "fr": "Ici, on joue au basketball", "en": "Basketball is played here", - "it": "Qui si gioca a basket" + "it": "Qui si gioca a basket", + "ru": "Здесь можно играть в баскетбол" }, "hideInAnswer": true } @@ -141,7 +147,8 @@ "nl": "Wat is de ondergrond van dit sportveld?", "fr": "De quelle surface est fait ce terrain de sport ?", "en": "Which is the surface of this sport pitch?", - "it": "Qual è la superficie di questo campo sportivo?" + "it": "Qual è la superficie di questo campo sportivo?", + "ru": "Какое покрытие на этой спортивной площадке?" }, "render": { "nl": "De ondergrond is {surface}", @@ -211,7 +218,8 @@ "nl": "Is dit sportterrein publiek toegankelijk?", "fr": "Est-ce que ce terrain de sport est accessible au public ?", "en": "Is this sport pitch publicly accessible?", - "it": "Questo campo sportivo è aperto al pubblico?" + "it": "Questo campo sportivo è aperto al pubblico?", + "ru": "Есть ли свободный доступ к этой спортивной площадке?" }, "mappings": [ { @@ -220,7 +228,8 @@ "nl": "Publiek toegankelijk", "fr": "Accessible au public", "en": "Public access", - "it": "Aperto al pubblico" + "it": "Aperto al pubblico", + "ru": "Свободный доступ" } }, { @@ -229,7 +238,8 @@ "nl": "Beperkt toegankelijk (enkel na reservatie, tijdens bepaalde uren, ...)", "fr": "Accès limité (par exemple uniquement sur réservation, à certains horaires…)", "en": "Limited access (e.g. only with an appointment, during certain hours, ...)", - "it": "Accesso limitato (p.es. solo con prenotazione, in certi orari, ...)" + "it": "Accesso limitato (p.es. solo con prenotazione, in certi orari, ...)", + "ru": "Ограниченный доступ (напр., только по записи, в определённые часы, ...)" } }, { @@ -238,7 +248,8 @@ "nl": "Enkel toegankelijk voor leden van de bijhorende sportclub", "fr": "Accessible uniquement aux membres du club", "en": "Only accessible for members of the club", - "it": "Accesso limitato ai membri dell'associazione" + "it": "Accesso limitato ai membri dell'associazione", + "ru": "Доступ только членам клуба" } }, { @@ -257,7 +268,8 @@ "nl": "Moet men reserveren om gebruik te maken van dit sportveld?", "fr": "Doit-on réserver pour utiliser ce terrain de sport ?", "en": "Does one have to make an appointment to use this sport pitch?", - "it": "È necessario prenotarsi per usare questo campo sportivo?" + "it": "È necessario prenotarsi per usare questo campo sportivo?", + "ru": "Нужна ли предварительная запись для доступа на эту спортивную площадку?" }, "condition": { "and": [ @@ -282,7 +294,8 @@ "nl": "Reserveren is sterk aangeraden om gebruik te maken van dit sportterrein", "fr": "Il est recommendé de réserver pour utiliser ce terrain de sport", "en": "Making an appointment is recommended when using this sport pitch", - "it": "La prenotazione è consigliata per usare questo campo sportivo" + "it": "La prenotazione è consigliata per usare questo campo sportivo", + "ru": "Желательна предварительная запись для доступа на эту спортивную площадку" } }, { @@ -291,7 +304,8 @@ "nl": "Reserveren is mogelijk, maar geen voorwaarde", "fr": "Il est possible de réserver, mais ce n'est pas nécéssaire pour utiliser ce terrain de sport", "en": "Making an appointment is possible, but not necessary to use this sport pitch", - "it": "La prenotazione è consentita, ma non è obbligatoria per usare questo campo sportivo" + "it": "La prenotazione è consentita, ma non è obbligatoria per usare questo campo sportivo", + "ru": "Предварительная запись для доступа на эту спортивную площадку возможна, но не обязательна" } }, { @@ -300,7 +314,8 @@ "nl": "Reserveren is niet mogelijk", "fr": "On ne peut pas réserver", "en": "Making an appointment is not possible", - "it": "Non è possibile prenotare" + "it": "Non è possibile prenotare", + "ru": "Невозможна предварительная запись" } } ] @@ -336,7 +351,8 @@ "nl": "Wanneer is dit sportveld toegankelijk?", "fr": "Quand ce terrain est-il accessible ?", "en": "When is this pitch accessible?", - "it": "Quando è aperto questo campo sportivo?" + "it": "Quando è aperto questo campo sportivo?", + "ru": "В какое время доступна эта площадка?" }, "render": "Openingsuren: {opening_hours_table()}", "freeform": { @@ -446,7 +462,8 @@ "nl": "Ping-pong tafel", "fr": "Table de ping-pong", "en": "Tabletennis table", - "it": "Tavolo da tennistavolo" + "it": "Tavolo da tennistavolo", + "ru": "Стол для настольного тенниса" }, "tags": [ "leisure=pitch", diff --git a/assets/layers/surveillance_camera/surveillance_camera.json b/assets/layers/surveillance_camera/surveillance_camera.json index e5c872be2..20f1e77bf 100644 --- a/assets/layers/surveillance_camera/surveillance_camera.json +++ b/assets/layers/surveillance_camera/surveillance_camera.json @@ -39,7 +39,8 @@ "en": "What kind of camera is this?", "nl": "Wat voor soort camera is dit?", "fr": "Quel genre de caméra est-ce ?", - "it": "Di che tipo di videocamera si tratta?" + "it": "Di che tipo di videocamera si tratta?", + "ru": "Какая это камера?" }, "mappings": [ { @@ -65,7 +66,8 @@ "en": "A dome camera (which can turn)", "nl": "Een dome (bolvormige camera die kan draaien)", "fr": "Une caméra dôme (qui peut tourner)", - "it": "Una videocamera a cupola (che può ruotare)" + "it": "Una videocamera a cupola (che può ruotare)", + "ru": "Камера с поворотным механизмом" } }, { @@ -230,7 +232,8 @@ "en": "This camera is located outdoors", "nl": "Deze camera bevindt zich buiten", "fr": "Cette caméra est située à l'extérieur", - "it": "Questa videocamera si trova all'aperto" + "it": "Questa videocamera si trova all'aperto", + "ru": "Эта камера расположена снаружи" } }, { @@ -239,7 +242,8 @@ "en": "This camera is probably located outdoors", "nl": "Deze camera bevindt zich waarschijnlijk buiten", "fr": "Cette caméra est probablement située à l'extérieur", - "it": "Questa videocamera si trova probabilmente all'esterno" + "it": "Questa videocamera si trova probabilmente all'esterno", + "ru": "Возможно, эта камера расположена снаружи" }, "hideInAnswer": true } @@ -374,7 +378,8 @@ "en": "How is this camera placed?", "nl": "Hoe is deze camera geplaatst?", "fr": "Comment cette caméra est-elle placée ?", - "it": "Com'è posizionata questa telecamera?" + "it": "Com'è posizionata questa telecamera?", + "ru": "Как расположена эта камера?" }, "render": { "en": "Mounting method: {mount}", diff --git a/assets/layers/toilet/toilet.json b/assets/layers/toilet/toilet.json index 06ea04860..a33ddf742 100644 --- a/assets/layers/toilet/toilet.json +++ b/assets/layers/toilet/toilet.json @@ -57,7 +57,8 @@ "de": "Eine öffentlich zugängliche Toilette", "fr": "Des toilettes", "nl": "Een publieke toilet", - "it": "Servizi igienici aperti al pubblico" + "it": "Servizi igienici aperti al pubblico", + "ru": "Туалет или комната отдыха со свободным доступом" } }, { @@ -66,7 +67,8 @@ "de": "Toiletten mit rollstuhlgerechter Toilette", "fr": "Toilettes accessible aux personnes à mobilité réduite", "nl": "Een rolstoeltoegankelijke toilet", - "it": "Servizi igienici accessibili per persone in sedia a rotelle" + "it": "Servizi igienici accessibili per persone in sedia a rotelle", + "ru": "Туалет с доступом для пользователей кресел-колясок" }, "tags": [ "amenity=toilets", @@ -89,7 +91,8 @@ "de": "Sind diese Toiletten öffentlich zugänglich?", "fr": "Ces toilettes sont-elles accessibles au public ?", "nl": "Zijn deze toiletten publiek toegankelijk?", - "it": "Questi servizi igienici sono aperti al pubblico?" + "it": "Questi servizi igienici sono aperti al pubblico?", + "ru": "Есть ли свободный доступ к этим туалетам?" }, "render": { "en": "Access is {access}", @@ -112,7 +115,8 @@ "de": "Öffentlicher Zugang", "fr": "Accès publique", "nl": "Publiek toegankelijk", - "it": "Accesso pubblico" + "it": "Accesso pubblico", + "ru": "Свободный доступ" } }, { @@ -186,14 +190,16 @@ "de": "Wie viel muss man für diese Toiletten bezahlen?", "fr": "Quel est le prix d'accès de ces toilettes ?", "nl": "Hoeveel moet men betalen om deze toiletten te gebruiken?", - "it": "Quanto costa l'accesso a questi servizi igienici?" + "it": "Quanto costa l'accesso a questi servizi igienici?", + "ru": "Сколько стоит посещение туалета?" }, "render": { "en": "The fee is {charge}", "de": "Die Gebühr beträgt {charge}", "fr": "Le prix est {charge}", "nl": "De toiletten gebruiken kost {charge}", - "it": "La tariffa è {charge}" + "it": "La tariffa è {charge}", + "ru": "Стоимость {charge}" }, "condition": "fee=yes", "freeform": { @@ -227,7 +233,8 @@ "de": "Kein Zugang für Rollstuhlfahrer", "fr": "Non accessible aux personnes à mobilité réduite", "nl": "Niet toegankelijk voor rolstoelgebruikers", - "it": "Non accessibile in sedia a rotelle" + "it": "Non accessibile in sedia a rotelle", + "ru": "Недоступно пользователям кресел-колясок" } } ] @@ -238,7 +245,8 @@ "de": "Welche Art von Toiletten sind das?", "fr": "De quel type sont ces toilettes ?", "nl": "Welke toiletten zijn dit?", - "it": "Di che tipo di servizi igienici si tratta?" + "it": "Di che tipo di servizi igienici si tratta?", + "ru": "Какие это туалеты?" }, "mappings": [ { diff --git a/assets/layers/tree_node/tree_node.json b/assets/layers/tree_node/tree_node.json index a95bfdb01..1f3cc7fde 100644 --- a/assets/layers/tree_node/tree_node.json +++ b/assets/layers/tree_node/tree_node.json @@ -230,7 +230,8 @@ "question": { "nl": "Is deze boom groenblijvend of bladverliezend?", "en": "Is this tree evergreen or deciduous?", - "it": "È un sempreverde o caduco?" + "it": "È un sempreverde o caduco?", + "ru": "Это дерево вечнозелёное или листопадное?" }, "mappings": [ { @@ -242,7 +243,8 @@ "then": { "nl": "Bladverliezend: de boom is een periode van het jaar kaal.", "en": "Deciduous: the tree loses its leaves for some time of the year.", - "it": "Caduco: l’albero perde le sue foglie per un periodo dell’anno." + "it": "Caduco: l’albero perde le sue foglie per un periodo dell’anno.", + "ru": "Листопадное: у дерева опадают листья в определённое время года." } }, { @@ -255,7 +257,8 @@ "nl": "Groenblijvend.", "en": "Evergreen.", "it": "Sempreverde.", - "fr": "À feuilles persistantes." + "fr": "À feuilles persistantes.", + "ru": "Вечнозелёное." } } ], @@ -278,7 +281,8 @@ "nl": "Heeft de boom een naam?", "en": "Does the tree have a name?", "it": "L’albero ha un nome?", - "fr": "L'arbre a-t-il un nom ?" + "fr": "L'arbre a-t-il un nom ?", + "ru": "Есть ли у этого дерева название?" }, "freeform": { "key": "name", @@ -298,7 +302,8 @@ "nl": "De boom heeft geen naam.", "en": "The tree does not have a name.", "it": "L’albero non ha un nome.", - "fr": "L'arbre n'a pas de nom." + "fr": "L'arbre n'a pas de nom.", + "ru": "У этого дерева нет названия." } } ], @@ -399,7 +404,8 @@ "render": { "nl": "\"\"/ Onroerend Erfgoed-ID: {ref:OnroerendErfgoed}", "en": "\"\"/ Onroerend Erfgoed ID: {ref:OnroerendErfgoed}", - "it": "\"\"/ Onroerend Erfgoed ID: {ref:OnroerendErfgoed}" + "it": "\"\"/ Onroerend Erfgoed ID: {ref:OnroerendErfgoed}", + "ru": "\"\"/ Onroerend Erfgoed ID: {ref:OnroerendErfgoed}" }, "question": { "nl": "Wat is het ID uitgegeven door Onroerend Erfgoed Vlaanderen?", @@ -421,7 +427,8 @@ "render": { "nl": "\"\"/ Wikidata: {wikidata}", "en": "\"\"/ Wikidata: {wikidata}", - "it": "\"\"/ Wikidata: {wikidata}" + "it": "\"\"/ Wikidata: {wikidata}", + "ru": "\"\"/ Wikidata: {wikidata}" }, "question": { "nl": "Wat is het Wikidata-ID van deze boom?", @@ -484,7 +491,8 @@ "nl": "Loofboom", "en": "Broadleaved tree", "it": "Albero latifoglia", - "fr": "Arbre feuillu" + "fr": "Arbre feuillu", + "ru": "Лиственное дерево" }, "description": { "nl": "Een boom van een soort die blaadjes heeft, bijvoorbeeld eik of populier.", @@ -501,12 +509,14 @@ "title": { "nl": "Naaldboom", "en": "Needleleaved tree", - "it": "Albero aghifoglia" + "it": "Albero aghifoglia", + "ru": "Хвойное дерево" }, "description": { "nl": "Een boom van een soort met naalden, bijvoorbeeld den of spar.", "en": "A tree of a species with needles, such as pine or spruce.", - "it": "Un albero di una specie con aghi come il pino o l’abete." + "it": "Un albero di una specie con aghi come il pino o l’abete.", + "ru": "Дерево с хвоей (иглами), например, сосна или ель." } }, { @@ -524,7 +534,8 @@ "nl": "Wanneer je niet zeker bent of het nu een loof- of naaldboom is.", "en": "If you're not sure whether it's a broadleaved or needleleaved tree.", "it": "Qualora non si sia sicuri se si tratta di un albero latifoglia o aghifoglia.", - "fr": "Si vous n'êtes pas sûr(e) de savoir s'il s'agit d'un arbre à feuilles larges ou à aiguilles." + "fr": "Si vous n'êtes pas sûr(e) de savoir s'il s'agit d'un arbre à feuilles larges ou à aiguilles.", + "ru": "Если вы не уверены в том, лиственное это дерево или хвойное." } } ] diff --git a/assets/themes/charging_stations/charging_stations.json b/assets/themes/charging_stations/charging_stations.json index fc5040c6c..159cd5819 100644 --- a/assets/themes/charging_stations/charging_stations.json +++ b/assets/themes/charging_stations/charging_stations.json @@ -6,7 +6,8 @@ "ru": "Зарядные станции", "ja": "充電ステーション", "zh_Hant": "充電站", - "it": "Stazioni di ricarica" + "it": "Stazioni di ricarica", + "nl": "Oplaadpunten" }, "shortDescription": { "en": "A worldwide map of charging stations", @@ -29,6 +30,7 @@ "ja", "zh_Hant", "it", + "nl", "nb_NO" ], "maintainer": "", @@ -48,7 +50,8 @@ "ja": "充電ステーション", "zh_Hant": "充電站", "nb_NO": "Ladestasjoner", - "it": "Stazioni di ricarica" + "it": "Stazioni di ricarica", + "nl": "Oplaadpunten" }, "minzoom": 10, "source": { @@ -65,7 +68,8 @@ "ja": "充電ステーション", "zh_Hant": "充電站", "nb_NO": "Ladestasjon", - "it": "Stazione di ricarica" + "it": "Stazione di ricarica", + "nl": "Oplaadpunt" } }, "description": { @@ -74,7 +78,8 @@ "ja": "充電ステーション", "zh_Hant": "充電站", "nb_NO": "En ladestasjon", - "it": "Una stazione di ricarica" + "it": "Una stazione di ricarica", + "nl": "Een oplaadpunt" }, "tagRenderings": [ "images", diff --git a/assets/themes/shops/shops.json b/assets/themes/shops/shops.json index e50029a62..3883a9ef8 100644 --- a/assets/themes/shops/shops.json +++ b/assets/themes/shops/shops.json @@ -23,6 +23,7 @@ "ja", "zh_Hant", "ru", + "nl", "ca", "id" ], @@ -41,7 +42,8 @@ "en": "Shop", "fr": "Magasin", "ru": "Магазин", - "ja": "店" + "ja": "店", + "nl": "Winkel" }, "minzoom": 16, "source": { @@ -56,7 +58,8 @@ "en": "Shop", "fr": "Magasin", "ru": "Магазин", - "ja": "店" + "ja": "店", + "nl": "Winkel" }, "mappings": [ { @@ -90,7 +93,8 @@ "description": { "en": "A shop", "fr": "Un magasin", - "ja": "ショップ" + "ja": "ショップ", + "nl": "Een winkel" }, "tagRenderings": [ "images", @@ -99,7 +103,8 @@ "en": "What is the name of this shop?", "fr": "Qu'est-ce que le nom de ce magasin?", "ru": "Как называется магазин?", - "ja": "このお店の名前は何ですか?" + "ja": "このお店の名前は何ですか?", + "nl": "Wat is de naam van deze winkel?" }, "render": "This shop is called {name}", "freeform": { @@ -143,7 +148,8 @@ "en": "Supermarket", "fr": "Supermarché", "ru": "Супермаркет", - "ja": "スーパーマーケット" + "ja": "スーパーマーケット", + "nl": "Supermarkt" } }, { @@ -169,7 +175,8 @@ "en": "Hairdresser", "fr": "Coiffeur", "ru": "Парикмахерская", - "ja": "理容師" + "ja": "理容師", + "nl": "Kapper" } }, { @@ -181,7 +188,8 @@ "then": { "en": "Bakery", "fr": "Boulangerie", - "ja": "ベーカリー" + "ja": "ベーカリー", + "nl": "Bakkerij" } }, { @@ -223,7 +231,8 @@ "question": { "en": "What is the phone number?", "fr": "Quel est le numéro de téléphone ?", - "ja": "電話番号は何番ですか?" + "ja": "電話番号は何番ですか?", + "nl": "Wat is het telefoonnummer?" }, "freeform": { "key": "phone", @@ -242,7 +251,8 @@ "question": { "en": "What is the website of this shop?", "fr": "Quel est le site internet de ce magasin ?", - "ja": "このお店のホームページは何ですか?" + "ja": "このお店のホームページは何ですか?", + "nl": "Wat is de website van deze winkel?" }, "freeform": { "key": "website", @@ -277,7 +287,8 @@ "question": { "en": "What are the opening hours of this shop?", "fr": "Quels sont les horaires d'ouverture de ce magasin ?", - "ja": "この店の営業時間は何時から何時までですか?" + "ja": "この店の営業時間は何時から何時までですか?", + "nl": "Wat zijn de openingsuren van deze winkel?" }, "freeform": { "key": "opening_hours", @@ -316,13 +327,15 @@ "en": "Shop", "fr": "Magasin", "ru": "Магазин", - "ja": "店" + "ja": "店", + "nl": "Winkel" }, "description": { "en": "Add a new shop", "fr": "Ajouter un nouveau magasin", "ru": "Добавить новый магазин", - "ja": "新しい店を追加する" + "ja": "新しい店を追加する", + "nl": "Voeg een nieuwe winkel toe" } } ], diff --git a/langs/layers/ru.json b/langs/layers/ru.json index 55015961a..0cd328a6a 100644 --- a/langs/layers/ru.json +++ b/langs/layers/ru.json @@ -603,8 +603,11 @@ "title": { "render": "Стол для пикника" }, + "description": "Слой, отображающий столы для пикника", "tagRenderings": { "0": { + "question": "Из чего изготовлен этот стол для пикника?", + "render": "Этот стол для пикника сделан из {material}", "mappings": { "0": { "then": "Это деревянный стол для пикника" @@ -612,17 +615,14 @@ "1": { "then": "Это бетонный стол для пикника" } - }, - "render": "Этот стол для пикника сделан из {material}", - "question": "Из чего изготовлен этот стол для пикника?" + } } }, "presets": { "0": { "title": "Стол для пикника" } - }, - "description": "Слой, отображающий столы для пикника" + } }, "playground": { "name": "Детские площадки", @@ -645,6 +645,9 @@ "1": { "then": "Поверхность - песок" }, + "2": { + "then": "Покрытие из щепы" + }, "3": { "then": "Поверхность - брусчатка" }, @@ -653,9 +656,17 @@ }, "5": { "then": "Поверхность - бетон" + } + } + }, + "2": { + "question": "Эта игровая площадка освещается ночью?", + "mappings": { + "0": { + "then": "Эта детская площадка освещается ночью" }, - "2": { - "then": "Покрытие из щепы" + "1": { + "then": "Эта детская площадка не освещается ночью" } } }, @@ -663,6 +674,9 @@ "render": "Доступно для детей старше {min_age} лет", "question": "С какого возраста доступна эта детская площадка?" }, + "4": { + "render": "Доступно детям до {max_age}" + }, "6": { "mappings": { "4": { @@ -676,47 +690,33 @@ "8": { "render": "{phone}" }, - "10": { - "mappings": { - "1": { - "then": "Всегда доступен" - }, - "2": { - "then": "Всегда доступен" - }, - "0": { - "then": "Открыто от рассвета до заката" - } - }, - "question": "Когда открыта эта игровая площадка?" - }, "9": { + "question": "Доступна ли детская площадка пользователям кресел-колясок?", "mappings": { - "2": { - "then": "Недоступна пользователям кресел-колясок" + "0": { + "then": "Полностью доступна пользователям кресел-колясок" }, "1": { "then": "Частично доступна пользователям кресел-колясок" }, - "0": { - "then": "Полностью доступна пользователям кресел-колясок" + "2": { + "then": "Недоступна пользователям кресел-колясок" } - }, - "question": "Доступна ли детская площадка пользователям кресел-колясок?" + } }, - "4": { - "render": "Доступно детям до {max_age}" - }, - "2": { + "10": { + "question": "Когда открыта эта игровая площадка?", "mappings": { - "1": { - "then": "Эта детская площадка не освещается ночью" - }, "0": { - "then": "Эта детская площадка освещается ночью" + "then": "Открыто от рассвета до заката" + }, + "1": { + "then": "Всегда доступен" + }, + "2": { + "then": "Всегда доступен" } - }, - "question": "Эта игровая площадка освещается ночью?" + } } }, "presets": { @@ -727,6 +727,7 @@ }, "public_bookcase": { "name": "Книжные шкафы", + "description": "Уличный шкаф с книгами, доступными для всех", "title": { "render": "Книжный шкаф", "mappings": { @@ -751,10 +752,11 @@ } }, "3": { - "question": "Сколько книг помещается в этом общественном книжном шкафу?", - "render": "{capacity} книг помещается в этот книжный шкаф" + "render": "{capacity} книг помещается в этот книжный шкаф", + "question": "Сколько книг помещается в этом общественном книжном шкафу?" }, "4": { + "question": "Какие книги можно найти в этом общественном книжном шкафу?", "mappings": { "0": { "then": "В основном детские книги" @@ -765,27 +767,25 @@ "2": { "then": "Книги и для детей, и для взрослых" } - }, - "question": "Какие книги можно найти в этом общественном книжном шкафу?" - }, - "11": { - "render": "Более подробная информация на сайте", - "question": "Есть ли веб-сайт с более подробной информацией об этом общественном книжном шкафе?" - }, - "10": { - "render": "Установлен {start_date}", - "question": "Когда был установлен этот общественный книжный шкаф?" + } }, "6": { + "question": "Имеется ли свободный доступ к этому общественному книжному шкафу?", "mappings": { "0": { "then": "Свободный доступ" } - }, - "question": "Имеется ли свободный доступ к этому общественному книжному шкафу?" + } + }, + "10": { + "question": "Когда был установлен этот общественный книжный шкаф?", + "render": "Установлен {start_date}" + }, + "11": { + "render": "Более подробная информация на сайте", + "question": "Есть ли веб-сайт с более подробной информацией об этом общественном книжном шкафе?" } - }, - "description": "Уличный шкаф с книгами, доступными для всех" + } }, "slow_roads": { "tagRenderings": { @@ -819,30 +819,32 @@ "title": { "render": "Спортивная площадка" }, + "description": "Спортивная площадка", "tagRenderings": { "1": { "mappings": { - "2": { - "then": "Это стол для пинг-понга" - }, - "5": { + "0": { "then": "Здесь можно играть в баскетбол" }, - "4": { - "then": "Здесь можно играть в корфбол" - }, - "3": { - "then": "Здесь можно играть в теннис" - }, "1": { "then": "Здесь можно играть в футбол" }, - "0": { + "2": { + "then": "Это стол для пинг-понга" + }, + "3": { + "then": "Здесь можно играть в теннис" + }, + "4": { + "then": "Здесь можно играть в корфбол" + }, + "5": { "then": "Здесь можно играть в баскетбол" } } }, "2": { + "question": "Какое покрытие на этой спортивной площадке?", "render": "Поверхность - {surface}", "mappings": { "0": { @@ -860,55 +862,53 @@ "4": { "then": "Поверхность - бетон" } - }, - "question": "Какое покрытие на этой спортивной площадке?" - }, - "7": { - "mappings": { - "1": { - "then": "Всегда доступен" - } - }, - "question": "В какое время доступна эта площадка?" - }, - "4": { - "mappings": { - "1": { - "then": "Желательна предварительная запись для доступа на эту спортивную площадку" - }, - "3": { - "then": "Невозможна предварительная запись" - }, - "2": { - "then": "Предварительная запись для доступа на эту спортивную площадку возможна, но не обязательна" - } - }, - "question": "Нужна ли предварительная запись для доступа на эту спортивную площадку?" + } }, "3": { + "question": "Есть ли свободный доступ к этой спортивной площадке?", "mappings": { - "2": { - "then": "Доступ только членам клуба" + "0": { + "then": "Свободный доступ" }, "1": { "then": "Ограниченный доступ (напр., только по записи, в определённые часы, ...)" }, - "0": { - "then": "Свободный доступ" + "2": { + "then": "Доступ только членам клуба" } - }, - "question": "Есть ли свободный доступ к этой спортивной площадке?" + } + }, + "4": { + "question": "Нужна ли предварительная запись для доступа на эту спортивную площадку?", + "mappings": { + "1": { + "then": "Желательна предварительная запись для доступа на эту спортивную площадку" + }, + "2": { + "then": "Предварительная запись для доступа на эту спортивную площадку возможна, но не обязательна" + }, + "3": { + "then": "Невозможна предварительная запись" + } + } + }, + "7": { + "question": "В какое время доступна эта площадка?", + "mappings": { + "1": { + "then": "Всегда доступен" + } + } } }, "presets": { - "1": { - "title": "Спортивная площадка" - }, "0": { "title": "Стол для настольного тенниса" + }, + "1": { + "title": "Спортивная площадка" } - }, - "description": "Спортивная площадка" + } }, "surveillance_camera": { "name": "Камеры наблюдения", @@ -917,28 +917,28 @@ }, "tagRenderings": { "1": { + "question": "Какая это камера?", "mappings": { - "2": { - "then": "Панорамная камера" - }, "1": { "then": "Камера с поворотным механизмом" + }, + "2": { + "then": "Панорамная камера" } - }, - "question": "Какая это камера?" - }, - "8": { - "question": "Как расположена эта камера?" + } }, "5": { "mappings": { - "2": { - "then": "Возможно, эта камера расположена снаружи" - }, "1": { "then": "Эта камера расположена снаружи" + }, + "2": { + "then": "Возможно, эта камера расположена снаружи" } } + }, + "8": { + "question": "Как расположена эта камера?" } } }, @@ -958,15 +958,15 @@ }, "tagRenderings": { "1": { + "question": "Есть ли свободный доступ к этим туалетам?", "mappings": { - "2": { - "then": "Недоступно" - }, "0": { "then": "Свободный доступ" + }, + "2": { + "then": "Недоступно" } - }, - "question": "Есть ли свободный доступ к этим туалетам?" + } }, "2": { "mappings": { @@ -975,8 +975,9 @@ } } }, - "5": { - "question": "Какие это туалеты?" + "3": { + "question": "Сколько стоит посещение туалета?", + "render": "Стоимость {charge}" }, "4": { "mappings": { @@ -985,9 +986,8 @@ } } }, - "3": { - "render": "Стоимость {charge}", - "question": "Сколько стоит посещение туалета?" + "5": { + "question": "Какие это туалеты?" } } }, @@ -1010,44 +1010,44 @@ } } }, + "4": { + "question": "Это дерево вечнозелёное или листопадное?", + "mappings": { + "0": { + "then": "Листопадное: у дерева опадают листья в определённое время года." + }, + "1": { + "then": "Вечнозелёное." + } + } + }, "5": { "render": "Название: {name}", + "question": "Есть ли у этого дерева название?", "mappings": { "0": { "then": "У этого дерева нет названия." } - }, - "question": "Есть ли у этого дерева название?" - }, - "8": { - "render": "\"\"/ Wikidata: {wikidata}" + } }, "7": { "render": "\"\"/ Onroerend Erfgoed ID: {ref:OnroerendErfgoed}" }, - "4": { - "mappings": { - "1": { - "then": "Вечнозелёное." - }, - "0": { - "then": "Листопадное: у дерева опадают листья в определённое время года." - } - }, - "question": "Это дерево вечнозелёное или листопадное?" + "8": { + "render": "\"\"/ Wikidata: {wikidata}" } }, "presets": { + "0": { + "title": "Лиственное дерево" + }, + "1": { + "title": "Хвойное дерево", + "description": "Дерево с хвоей (иглами), например, сосна или ель." + }, "2": { "title": "Дерево", "description": "Если вы не уверены в том, лиственное это дерево или хвойное." - }, - "1": { - "description": "Дерево с хвоей (иглами), например, сосна или ель.", - "title": "Хвойное дерево" - }, - "0": { - "title": "Лиственное дерево" } } }, diff --git a/langs/themes/nl.json b/langs/themes/nl.json index 6d7f84a0a..7966e9e2d 100644 --- a/langs/themes/nl.json +++ b/langs/themes/nl.json @@ -278,6 +278,18 @@ } } }, + "charging_stations": { + "title": "Oplaadpunten", + "layers": { + "0": { + "name": "Oplaadpunten", + "title": { + "render": "Oplaadpunt" + }, + "description": "Een oplaadpunt" + } + } + }, "climbing": { "title": "Open Klimkaart", "description": "Op deze kaart vind je verschillende klimgelegenheden, zoals klimzalen, bolderzalen en klimmen in de natuur", @@ -924,6 +936,50 @@ "shortDescription": "Een kaart met speeltuinen", "description": "Op deze kaart vind je speeltuinen en kan je zelf meer informatie en foto's toevoegen" }, + "shops": { + "layers": { + "0": { + "name": "Winkel", + "title": { + "render": "Winkel" + }, + "description": "Een winkel", + "tagRenderings": { + "1": { + "question": "Wat is de naam van deze winkel?" + }, + "2": { + "mappings": { + "1": { + "then": "Supermarkt" + }, + "3": { + "then": "Kapper" + }, + "4": { + "then": "Bakkerij" + } + } + }, + "3": { + "question": "Wat is het telefoonnummer?" + }, + "4": { + "question": "Wat is de website van deze winkel?" + }, + "6": { + "question": "Wat zijn de openingsuren van deze winkel?" + } + }, + "presets": { + "0": { + "title": "Winkel", + "description": "Voeg een nieuwe winkel toe" + } + } + } + } + }, "speelplekken": { "title": "Welkom bij de groendoener!", "shortDescription": "Speelplekken in de Antwerpse Zuidrand", @@ -1042,61 +1098,5 @@ } } } - }, - "charging_stations": { - "layers": { - "0": { - "description": "Een oplaadpunt", - "title": { - "render": "Oplaadpunt" - }, - "name": "Oplaadpunten" - } - }, - "title": "Oplaadpunten" - }, - "shops": { - "layers": { - "0": { - "tagRenderings": { - "4": { - "question": "Wat is de website van deze winkel?" - }, - "3": { - "question": "Wat is het telefoonnummer?" - }, - "2": { - "mappings": { - "4": { - "then": "Bakkerij" - }, - "3": { - "then": "Kapper" - }, - "1": { - "then": "Supermarkt" - } - } - }, - "1": { - "question": "Wat is de naam van deze winkel?" - }, - "6": { - "question": "Wat zijn de openingsuren van deze winkel?" - } - }, - "description": "Een winkel", - "title": { - "render": "Winkel" - }, - "name": "Winkel", - "presets": { - "0": { - "title": "Winkel", - "description": "Voeg een nieuwe winkel toe" - } - } - } - } } } \ No newline at end of file