Combine and reuse translations for keyboard shortcuts

Using i18next's "nesting" and "interpolation" features should reduce the
overall number of strings to translate, as well as provide a
standardized pattern for shortcut tooltips (if applicable).

Note that this approach is still allowing for flexibility regarding
differently structured sentences in each language.

Resolves #315
This commit is contained in:
Henrik Fehlauer 2020-06-21 18:00:00 +00:00
parent e3a9f6206f
commit 09f987ea07
9 changed files with 156 additions and 66 deletions

View file

@ -61,7 +61,8 @@
role="button" role="button"
aria-haspopup="true" aria-haspopup="true"
aria-expanded="false" aria-expanded="false"
data-i18n="[title]navbar.export-tooltip" data-i18n="[title]keyboard.generic-shortcut"
data-i18n-options='{ "action": "$t(navbar.export-tooltip)", "key": "X" }'
title="Export route" title="Export route"
> >
<span class="fa fa-lg fa-cloud-download" aria-hidden="true"> </span> <span class="fa fa-lg fa-cloud-download" aria-hidden="true"> </span>
@ -79,6 +80,12 @@
aria-haspopup="true" aria-haspopup="true"
aria-expanded="false" aria-expanded="false"
data-i18n="[title]navbar.load.tooltip" data-i18n="[title]navbar.load.tooltip"
data-i18n-options='{
"tracksAction": "$t(navbar.load.tracks)",
"tracksKey": "O",
"nogosAction": "$t(navbar.load.nogos)",
"nogosKey": "$t(keyboard.shift)+O"
}'
title="Load route" title="Load route"
> >
<span class="fa fa-lg fa-cloud-upload" aria-hidden="true"> </span> <span class="fa fa-lg fa-cloud-upload" aria-hidden="true"> </span>
@ -113,7 +120,8 @@
</div> </div>
<div <div
class="nav-item" class="nav-item"
data-i18n="[title]about.tooltip" data-i18n="[title]keyboard.generic-shortcut"
data-i18n-options='{ "action": "$t(about.tooltip)", "key": "H" }'
title="Show more information about BRouter-Web" title="Show more information about BRouter-Web"
> >
<a class="nav-link" href="#" data-toggle="modal" data-target="#about" <a class="nav-link" href="#" data-toggle="modal" data-target="#about"
@ -314,7 +322,7 @@
updated daily, see dates of updated daily, see dates of
<a href="https://brouter.de/brouter/segments4/" target="_blank">data files</a>. <a href="https://brouter.de/brouter/segments4/" target="_blank">data files</a>.
</p> </p>
<p data-i18n="[html]about.details"> <p id="aboutLinks" data-i18n="[html]about.details">
<i><a href="{{privacyPolicyUrl}}" target="_blank">Privacy Policy</a></i <i><a href="{{privacyPolicyUrl}}" target="_blank">Privacy Policy</a></i
>, >,
<i <i
@ -709,7 +717,12 @@
<a <a
href="#tab_layers_control" href="#tab_layers_control"
role="tab" role="tab"
data-i18n="[title]sidebar.layers.tooltip" data-i18n="[title]sidebar.tab-tooltip"
data-i18n-options='{
"action": "$t(sidebar.layers.tooltip)",
"toggleKey": "T",
"switchKey": "$t(keyboard.shift)+T"
}'
title="Select layers" title="Select layers"
> >
<!-- <!--
@ -738,7 +751,12 @@
<a <a
href="#tab_itinerary" href="#tab_itinerary"
role="tab" role="tab"
data-i18n="[title]sidebar.itinerary.tooltip" data-i18n="[title]sidebar.tab-tooltip"
data-i18n-options='{
"action": "$t(sidebar.itinerary.tooltip)",
"toggleKey": "T",
"switchKey": "$t(keyboard.shift)+T"
}'
title="Show Itinerary" title="Show Itinerary"
><i class="fa fa-map-signs"></i ><i class="fa fa-map-signs"></i
></a> ></a>
@ -747,7 +765,12 @@
<a <a
href="#tab_profile" href="#tab_profile"
role="tab" role="tab"
data-i18n="[title]sidebar.customize-profile.tooltip" data-i18n="[title]sidebar.tab-tooltip"
data-i18n-options='{
"action": "$t(sidebar.customize-profile.tooltip)",
"toggleKey": "T",
"switchKey": "$t(keyboard.shift)+T"
}'
title="Customize profile" title="Customize profile"
><i class="fa fa-wrench"></i ><i class="fa fa-wrench"></i
></a> ></a>
@ -756,7 +779,12 @@
<a <a
href="#tab_data" href="#tab_data"
role="tab" role="tab"
data-i18n="[title]sidebar.data.tooltip" data-i18n="[title]sidebar.tab-tooltip"
data-i18n-options='{
"action": "$t(sidebar.data.tooltip)",
"toggleKey": "T",
"switchKey": "$t(keyboard.shift)+T"
}'
title="Show detailed route data table" title="Show detailed route data table"
><i class="fa fa-table"></i ><i class="fa fa-table"></i
></a> ></a>
@ -765,7 +793,12 @@
<a <a
href="#tab_statistics" href="#tab_statistics"
role="tab" role="tab"
data-i18n="[title]sidebar.analysis.tooltip" data-i18n="[title]sidebar.tab-tooltip"
data-i18n-options='{
"action": "$t(sidebar.analysis.tooltip)",
"toggleKey": "T",
"switchKey": "$t(keyboard.shift)+T"
}'
title="Analyse route" title="Analyse route"
><i class="fa fa-pie-chart"></i ><i class="fa fa-pie-chart"></i
></a> ></a>
@ -1073,7 +1106,8 @@
id="elevation-btn" id="elevation-btn"
aria-expanded="false" aria-expanded="false"
aria-label="Toggle elevation chart" aria-label="Toggle elevation chart"
data-i18n="[title]footer.elevation-chart" data-i18n="[title]keyboard.generic-shortcut"
data-i18n-options='{ "action": "$t(footer.elevation-chart)", "key": "E" }'
title="Toggle elevation chart" title="Toggle elevation chart"
> >
<span class="fa fa-area-chart"></span> <span class="fa fa-area-chart"></span>

View file

@ -24,8 +24,8 @@ BR.Map = {
if (BR.Util.getResponsiveBreakpoint() >= '3md') { if (BR.Util.getResponsiveBreakpoint() >= '3md') {
L.control L.control
.zoom({ .zoom({
zoomInTitle: i18next.t('map.zoomInTitle'), zoomInTitle: i18next.t('keyboard.generic-shortcut', { action: '$t(map.zoomInTitle)', key: '+' }),
zoomOutTitle: i18next.t('map.zoomOutTitle') zoomOutTitle: i18next.t('keyboard.generic-shortcut', { action: '$t(map.zoomOutTitle)', key: '-' })
}) })
.addTo(map); .addTo(map);
} }
@ -105,7 +105,7 @@ BR.Map = {
var locationControl = L.control var locationControl = L.control
.locate({ .locate({
strings: { strings: {
title: i18next.t('map.locate-me') title: i18next.t('keyboard.generic-shortcut', { action: '$t(map.locate-me)', key: 'L' })
}, },
icon: 'fa fa-location-arrow', icon: 'fa fa-location-arrow',
iconLoading: 'fa fa-spinner fa-pulse' iconLoading: 'fa fa-spinner fa-pulse'

View file

@ -48,7 +48,7 @@ BR.RoutingOptions = L.Evented.extend({
// append shortcut text to tooltip // append shortcut text to tooltip
var button = $('#profile-alternative-form button')[0]; var button = $('#profile-alternative-form button')[0];
button.title = button.title + i18next.t('navbar.profile-tooltip'); button.title = button.title + i18next.t('navbar.profile-tooltip', { key: 'G' });
}, },
getOptions: function() { getOptions: function() {

View file

@ -46,7 +46,10 @@
search = new BR.Search(); search = new BR.Search();
map.addControl(search); map.addControl(search);
$('#map .leaflet-control-geocoder > button')[0].title = i18next.t('map.geocoder'); $('#map .leaflet-control-geocoder > button')[0].title = i18next.t('keyboard.generic-shortcut', {
action: '$t(map.geocoder)',
key: 'F'
});
router = L.bRouter(); //brouterCgi dummyRouter router = L.bRouter(); //brouterCgi dummyRouter
@ -59,7 +62,10 @@
routing.draw(false); routing.draw(false);
control.state('activate-draw'); control.state('activate-draw');
}, },
title: i18next.t('map.draw-route-stop') title: i18next.t('keyboard.generic-shortcut', {
action: '$t(map.draw-route-stop)',
key: '$t(keyboard.escape)'
})
}, },
{ {
stateName: 'activate-draw', stateName: 'activate-draw',
@ -68,7 +74,7 @@
routing.draw(true); routing.draw(true);
control.state('deactivate-draw'); control.state('deactivate-draw');
}, },
title: i18next.t('map.draw-route-start') title: i18next.t('keyboard.generic-shortcut', { action: '$t(map.draw-route-start)', key: 'D' })
} }
] ]
}); });
@ -78,7 +84,7 @@
function() { function() {
routing.reverse(); routing.reverse();
}, },
i18next.t('map.reverse-route') i18next.t('keyboard.generic-shortcut', { action: '$t(map.reverse-route)', key: 'R' })
); );
var deletePointButton = L.easyButton( var deletePointButton = L.easyButton(
@ -86,7 +92,7 @@
function() { function() {
routing.deleteLastPoint(); routing.deleteLastPoint();
}, },
i18next.t('map.delete-last-point') i18next.t('keyboard.generic-shortcut', { action: '$t(map.delete-last-point)', key: 'Z' })
); );
deleteRouteButton = L.easyButton( deleteRouteButton = L.easyButton(
@ -94,7 +100,7 @@
function() { function() {
clearRoute(); clearRoute();
}, },
i18next.t('map.clear-route-tooltip') i18next.t('keyboard.generic-shortcut', { action: '$t(map.clear-route)', key: '$t(keyboard.backspace)' })
); );
L.DomEvent.addListener( L.DomEvent.addListener(
@ -175,8 +181,11 @@
profile.update(evt.options); profile.update(evt.options);
}); });
BR.NogoAreas.MSG_BUTTON = i18next.t('map.nogo.draw'); BR.NogoAreas.MSG_BUTTON = i18next.t('keyboard.generic-shortcut', { action: '$t(map.nogo.draw)', key: 'N' });
BR.NogoAreas.MSG_BUTTON_CANCEL = i18next.t('map.nogo.cancel'); BR.NogoAreas.MSG_BUTTON_CANCEL = i18next.t('keyboard.generic-shortcut', {
action: '$t(map.nogo.cancel)',
key: '$t(keyboard.escape)'
});
BR.NogoAreas.MSG_CREATE = i18next.t('map.nogo.click-drag'); BR.NogoAreas.MSG_CREATE = i18next.t('map.nogo.click-drag');
BR.NogoAreas.MSG_DISABLED = i18next.t('map.nogo.edit'); BR.NogoAreas.MSG_DISABLED = i18next.t('map.nogo.edit');
BR.NogoAreas.MSG_ENABLED = i18next.t('map.nogo.help'); BR.NogoAreas.MSG_ENABLED = i18next.t('map.nogo.help');
@ -313,7 +322,7 @@
map.addControl( map.addControl(
new BR.OpacitySliderControl({ new BR.OpacitySliderControl({
id: 'route', id: 'route',
title: i18next.t('map.opacity-slider'), title: i18next.t('map.opacity-slider-shortcut', { action: '$t(map.opacity-slider)', key: 'M' }),
muteKeyCode: 77, // m muteKeyCode: 77, // m
callback: L.bind(routing.setOpacity, routing) callback: L.bind(routing.setOpacity, routing)
}) })
@ -456,8 +465,9 @@
} }
}, },
function(err, t) { function(err, t) {
jqueryI18next.init(i18next, $); jqueryI18next.init(i18next, $, { useOptionsAttr: true });
$('html').localize({ $('html').localize();
$('#aboutLinks').localize({
privacyPolicyUrl: BR.conf.privacyPolicyUrl || 'https://brouter.de/privacypolicy.html' privacyPolicyUrl: BR.conf.privacyPolicyUrl || 'https://brouter.de/privacypolicy.html'
}); });

View file

@ -25,7 +25,7 @@ BR.PoiMarkers = L.Control.extend({
onClick: function() { onClick: function() {
self.draw(true); self.draw(true);
}, },
title: i18next.t('map.draw-poi-start') title: i18next.t('keyboard.generic-shortcut', { action: '$t(map.draw-poi-start)', key: 'P' })
}, },
{ {
stateName: 'deactivate-poi', stateName: 'deactivate-poi',
@ -33,7 +33,10 @@ BR.PoiMarkers = L.Control.extend({
onClick: function() { onClick: function() {
self.draw(false); self.draw(false);
}, },
title: i18next.t('map.draw-poi-stop') title: i18next.t('keyboard.generic-shortcut', {
action: '$t(map.draw-poi-stop)',
key: '$t(keyboard.escape)'
})
} }
] ]
}).addTo(map); }).addTo(map);

View file

@ -21,7 +21,7 @@ BR.RoutingPathQuality = L.Control.extend({
this.providers = { this.providers = {
incline: { incline: {
title: i18next.t('map.route-quality-incline'), title: i18next.t('map.route-quality-shortcut', { action: '$t(map.route-quality-incline)', key: 'C' }),
icon: 'fa-line-chart', icon: 'fa-line-chart',
provider: new HotLineQualityProvider({ provider: new HotLineQualityProvider({
hotlineOptions: { hotlineOptions: {
@ -48,7 +48,7 @@ BR.RoutingPathQuality = L.Control.extend({
}) })
}, },
altitude: { altitude: {
title: i18next.t('map.route-quality-altitude'), title: i18next.t('map.route-quality-shortcut', { action: '$t(map.route-quality-altitude)', key: 'C' }),
icon: 'fa-area-chart', icon: 'fa-area-chart',
provider: new HotLineQualityProvider({ provider: new HotLineQualityProvider({
hotlineOptions: { hotlineOptions: {
@ -61,7 +61,7 @@ BR.RoutingPathQuality = L.Control.extend({
}) })
}, },
cost: { cost: {
title: i18next.t('map.route-quality-cost'), title: i18next.t('map.route-quality-shortcut', { action: '$t(map.route-quality-cost)', key: 'C' }),
icon: 'fa-usd', icon: 'fa-usd',
provider: new HotLineQualityProvider({ provider: new HotLineQualityProvider({
hotlineOptions: { hotlineOptions: {

View file

@ -1,8 +1,8 @@
BR.stravaSegments = function(map, layersControl) { BR.stravaSegments = function(map, layersControl) {
var stravaControl = L.control var stravaControl = L.control
.stravaSegments({ .stravaSegments({
runningTitle: i18next.t('map.strava-running'), runningTitle: i18next.t('map.strava-shortcut', { action: '$t(map.strava-running)', key: 'S' }),
bikingTitle: i18next.t('map.strava-biking'), bikingTitle: i18next.t('map.strava-shortcut', { action: '$t(map.strava-biking)', key: 'S' }),
loadingTitle: i18next.t('map.loading'), loadingTitle: i18next.t('map.loading'),
stravaToken: BR.keys.strava stravaToken: BR.keys.strava
}) })

View file

@ -12,7 +12,7 @@
"details": "<i><a href=\"{{privacyPolicyUrl}}\" target=\"_blank\">Privacy Policy</a></i>, \n<i><a href=\"https://github.com/nrenner/brouter-web#credits-and-licenses\" target=\"_blank\">Credits</a></i>,\n<i><a href=\"https://github.com/nrenner/brouter-web/blob/master/CHANGELOG.md\" target=\"_blank\">Changelog</a></i> and\n<i><a href=\"https://github.com/nrenner/brouter-web#readme\" target=\"_blank\">more info</a></i> on the client.", "details": "<i><a href=\"{{privacyPolicyUrl}}\" target=\"_blank\">Privacy Policy</a></i>, \n<i><a href=\"https://github.com/nrenner/brouter-web#credits-and-licenses\" target=\"_blank\">Credits</a></i>,\n<i><a href=\"https://github.com/nrenner/brouter-web/blob/master/CHANGELOG.md\" target=\"_blank\">Changelog</a></i> and\n<i><a href=\"https://github.com/nrenner/brouter-web#readme\" target=\"_blank\">more info</a></i> on the client.",
"support": "General discussions/questions, support", "support": "General discussions/questions, support",
"title": "About", "title": "About",
"tooltip": "Show more information about Brouter-Web (H key)" "tooltip": "Show more information about Brouter-Web"
}, },
"credits": { "credits": {
"brouter": "BRouter", "brouter": "BRouter",
@ -42,7 +42,7 @@
"ascend": "Ascend", "ascend": "Ascend",
"cost": "Cost", "cost": "Cost",
"distance": "Distance", "distance": "Distance",
"elevation-chart": "Toggle elevation chart (E key)", "elevation-chart": "Toggle elevation chart",
"energy-per-100km": "Energy per 100 km", "energy-per-100km": "Energy per 100 km",
"hours": "hours", "hours": "hours",
"hours-abbrev": "h", "hours-abbrev": "h",
@ -58,6 +58,12 @@
"total-energy": "Total Energy", "total-energy": "Total Energy",
"travel-time": "Travel time" "travel-time": "Travel time"
}, },
"keyboard": {
"backspace": "Backspace",
"escape": "Escape",
"generic-shortcut": "{{action}} ({{key}} key)",
"shift": "Shift"
},
"layers": { "layers": {
"add-base": "Add base layer", "add-base": "Add base layer",
"add-overlay": "Add overlay", "add-overlay": "Add overlay",
@ -82,19 +88,18 @@
"attribution-osm-long": "OpenStreetMap contributors", "attribution-osm-long": "OpenStreetMap contributors",
"attribution-osm-short": "OpenStreetMap", "attribution-osm-short": "OpenStreetMap",
"clear-route": "Clear route data", "clear-route": "Clear route data",
"clear-route-tooltip": "Clear route data (Backspace key)",
"copyright": "Copyright", "copyright": "Copyright",
"cycling": "Cycling", "cycling": "Cycling",
"delete-last-point": "Delete last point (Z key)", "delete-last-point": "Delete last point",
"delete-nogo-areas": "Delete all no-go areas", "delete-nogo-areas": "Delete all no-go areas",
"delete-pois": "Delete all points of interest", "delete-pois": "Delete all points of interest",
"delete-route": "Delete route", "delete-route": "Delete route",
"draw-poi-start": "Draw points of interest (P key)", "draw-poi-start": "Draw points of interest",
"draw-poi-stop": "Stop drawing points of interest (ESC key)", "draw-poi-stop": "Stop drawing points of interest",
"draw-route-start": "Draw route (D key)", "draw-route-start": "Draw route",
"draw-route-stop": "Stop drawing route (ESC key)", "draw-route-stop": "Stop drawing route",
"enter-poi-name": "Enter Point of Interest name", "enter-poi-name": "Enter Point of Interest name",
"geocoder": "Search (F key)", "geocoder": "Search",
"geocoder-placeholder": "Search…", "geocoder-placeholder": "Search…",
"hikebike-hillshading": "Hillshading", "hikebike-hillshading": "Hillshading",
"hiking": "Hiking", "hiking": "Hiking",
@ -115,25 +120,28 @@
"topo": "OpenTopoMap" "topo": "OpenTopoMap"
}, },
"loading": "Loading…", "loading": "Loading…",
"locate-me": "Show me where I am (L key)", "locate-me": "Show me where I am",
"nogo": { "nogo": {
"cancel": "Cancel drawing no-go area (ESC key)", "cancel": "Cancel drawing no-go area",
"click-drag": "Click and drag to draw circle", "click-drag": "Click and drag to draw circle",
"draw": "Draw circular no-go area (N key)", "draw": "Draw circular no-go area",
"edit": "Click to edit", "edit": "Click to edit",
"help": "&square; = move / resize, <span class=\"fa fa-trash-o\"></span> = delete,<br>click circle to quit editing" "help": "&square; = move / resize, <span class=\"fa fa-trash-o\"></span> = delete,<br>click circle to quit editing"
}, },
"opacity-slider": "Set transparency of route track and markers\n(Hold M key to mute temporarily)", "opacity-slider": "Set transparency of route track and markers",
"opacity-slider-shortcut": "{{action}}\n(Hold {{key}} key to mute temporarily)",
"preview": "Preview", "preview": "Preview",
"privacy": "Privacy", "privacy": "Privacy",
"reverse-route": "Reverse route (R key)", "reverse-route": "Reverse route",
"route-quality-altitude": "Altitude coding (C key to toggle)", "route-quality-altitude": "Altitude coding",
"route-quality-cost": "Cost coding (C key to toggle)", "route-quality-cost": "Cost coding",
"route-quality-incline": "Incline coding (C key to toggle)", "route-quality-incline": "Incline coding",
"strava-biking": "Show Strava biking segments\n(S key to toggle layer, click to reload for current area)", "route-quality-shortcut": "{{action}} ({{key}} key to toggle)",
"strava-running": "Show Strava running segments\n(S key to toggle layer, click to reload for current area)", "strava-biking": "Show Strava biking segments",
"zoomInTitle": "Zoom in (+ key)", "strava-running": "Show Strava running segments",
"zoomOutTitle": "Zoom out (- key)" "strava-shortcut": "{{action}}\n({{key}} key to toggle layer, click to reload for current area)",
"zoomInTitle": "Zoom in",
"zoomOutTitle": "Zoom out"
}, },
"modal": { "modal": {
"close": "Close" "close": "Close"
@ -147,12 +155,12 @@
"third": "3rd alternative" "third": "3rd alternative"
}, },
"export": "Export", "export": "Export",
"export-tooltip": "Export route (X key)", "export-tooltip": "Export route",
"load": { "load": {
"nogos": "No-go areas", "nogos": "Load no-go areas",
"title": "Load", "title": "Load",
"tooltip": "Load tracks (O key)\nLoad No-go areas (Shift+O)", "tooltip": "{{tracksAction}} ({{tracksKey}} key)\n{{nogosAction}} ({{nogosKey}})",
"tracks": "Tracks" "tracks": "Load tracks"
}, },
"profile": { "profile": {
"car-eco": "Car (economic)", "car-eco": "Car (economic)",
@ -176,7 +184,7 @@
"vm-forum-liegerad-schnell": "Recumbent bike (fast)", "vm-forum-liegerad-schnell": "Recumbent bike (fast)",
"vm-forum-velomobil-schnell": "Velomobile (fast)" "vm-forum-velomobil-schnell": "Velomobile (fast)"
}, },
"profile-tooltip": "\n(G key to switch)" "profile-tooltip": "\n({{key}} key to switch)"
}, },
"sidebar": { "sidebar": {
"analysis": { "analysis": {
@ -192,20 +200,20 @@
"unknown": "Unknown" "unknown": "Unknown"
}, },
"title": "Analysis", "title": "Analysis",
"tooltip": "Analyse route\n(T key to toggle, Shift+T to switch to next tab)" "tooltip": "Analyse route"
}, },
"customize-profile": { "customize-profile": {
"title": "Customize profile", "title": "Customize profile",
"tooltip": "Customize profile\n(T key to toggle, Shift+T to switch to next tab)" "tooltip": "Customize profile"
}, },
"data": { "data": {
"sync-map": "Synchronize map", "sync-map": "Synchronize map",
"title": "Data", "title": "Data",
"tooltip": "Show detailed route data table\n(T key to toggle, Shift+T to switch to next tab)" "tooltip": "Show detailed route data table"
}, },
"itinerary": { "itinerary": {
"title": "Itinerary", "title": "Itinerary",
"tooltip": "Show itinerary\n(T key to toggle, Shift+T to switch to next tab)" "tooltip": "Show itinerary"
}, },
"layers": { "layers": {
"category": { "category": {
@ -232,7 +240,7 @@
"type": "Type" "type": "Type"
}, },
"title": "Layers", "title": "Layers",
"tooltip": "Select layers\n(T key to toggle, Shift+T to switch to next tab)" "tooltip": "Select layers"
}, },
"profile": { "profile": {
"apply": "Apply", "apply": "Apply",
@ -242,7 +250,8 @@
"options": "Options", "options": "Options",
"placeholder": "Write your custom profile here.", "placeholder": "Write your custom profile here.",
"profile": "Profile" "profile": "Profile"
} },
"tab-tooltip": "{{action}}\n({{toggleKey}} key to toggle, {{switchKey}} to switch to next tab)"
}, },
"title": "BRouter web client", "title": "BRouter web client",
"trackasroute": { "trackasroute": {

View file

@ -1,4 +1,33 @@
// this file contains translatable keys that are dynamic / not visible by i18n extractor tool // this file contains translatable keys that are dynamic / not visible by i18n extractor tool
i18next.t('about.tooltip');
i18next.t('footer.elevation-chart');
i18next.t('keyboard.backspace');
i18next.t('keyboard.escape');
i18next.t('keyboard.shift');
i18next.t('map.delete-last-point');
i18next.t('map.draw-poi-start');
i18next.t('map.draw-poi-stop');
i18next.t('map.draw-route-start');
i18next.t('map.draw-route-stop');
i18next.t('map.geocoder');
i18next.t('map.locate-me');
i18next.t('map.nogo.cancel');
i18next.t('map.nogo.draw');
i18next.t('map.opacity-slider');
i18next.t('map.reverse-route');
i18next.t('map.route-quality-altitude');
i18next.t('map.route-quality-cost');
i18next.t('map.route-quality-incline');
i18next.t('map.strava-biking');
i18next.t('map.strava-running');
i18next.t('map.zoomInTitle');
i18next.t('map.zoomOutTitle');
i18next.t('navbar.export-tooltip');
i18next.t('navbar.profile.car-eco'); i18next.t('navbar.profile.car-eco');
i18next.t('navbar.profile.car-fast'); i18next.t('navbar.profile.car-fast');
i18next.t('navbar.profile.car-test'); i18next.t('navbar.profile.car-test');
@ -20,11 +49,16 @@ i18next.t('navbar.profile.trekking-steep');
i18next.t('navbar.profile.vm-forum-liegerad-schnell'); i18next.t('navbar.profile.vm-forum-liegerad-schnell');
i18next.t('navbar.profile.vm-forum-velomobil-schnell'); i18next.t('navbar.profile.vm-forum-velomobil-schnell');
i18next.t('sidebar.analysis.tooltip');
i18next.t('sidebar.customize-profile.tooltip');
i18next.t('sidebar.data.tooltip');
i18next.t('sidebar.itinerary.tooltip');
i18next.t('sidebar.layers.category.base-layers', 'Base layers'); i18next.t('sidebar.layers.category.base-layers', 'Base layers');
i18next.t('sidebar.layers.category.worldwide-international', 'Worldwide international'); i18next.t('sidebar.layers.category.country', 'Country');
i18next.t('sidebar.layers.category.worldwide-monolingual', 'Worldwide monolingual');
i18next.t('sidebar.layers.category.europe', 'Europe'); i18next.t('sidebar.layers.category.europe', 'Europe');
i18next.t('sidebar.layers.category.europe-monolingual', 'Europe monolingual'); i18next.t('sidebar.layers.category.europe-monolingual', 'Europe monolingual');
i18next.t('sidebar.layers.category.country', 'Country');
i18next.t('sidebar.layers.category.overlays', 'Overlays'); i18next.t('sidebar.layers.category.overlays', 'Overlays');
i18next.t('sidebar.layers.category.worldwide', 'Worldwide'); i18next.t('sidebar.layers.category.worldwide', 'Worldwide');
i18next.t('sidebar.layers.category.worldwide-international', 'Worldwide international');
i18next.t('sidebar.layers.category.worldwide-monolingual', 'Worldwide monolingual');
i18next.t('sidebar.layers.tooltip');