From fd3cf02af4f3369252f1cec2c1a11e0f996eb715 Mon Sep 17 00:00:00 2001 From: DennisSchiefer Date: Thu, 29 Mar 2012 16:55:12 +0100 Subject: [PATCH] complete restructure of OSRM.Routing --- WebContent/OSRM.Geocoder.js | 2 +- WebContent/OSRM.Map.js | 6 +- WebContent/OSRM.Markers.js | 7 +- WebContent/OSRM.Routing.js | 45 +++-- WebContent/OSRM.Via.js | 2 +- WebContent/main.html | 20 +- WebContent/main.js | 2 +- WebContent/routing/OSRM.Routing.js | 148 +++++++++++++++ WebContent/routing/OSRM.RoutingDescription.js | 173 ++++++++++++++++++ WebContent/routing/OSRM.RoutingGUI.js | 94 ++++++++++ WebContent/routing/OSRM.RoutingGeometry.js | 71 +++++++ WebContent/routing/OSRM.RoutingNoNames.js | 68 +++++++ 12 files changed, 608 insertions(+), 30 deletions(-) create mode 100644 WebContent/routing/OSRM.Routing.js create mode 100644 WebContent/routing/OSRM.RoutingDescription.js create mode 100644 WebContent/routing/OSRM.RoutingGUI.js create mode 100644 WebContent/routing/OSRM.RoutingGeometry.js create mode 100644 WebContent/routing/OSRM.RoutingNoNames.js diff --git a/WebContent/OSRM.Geocoder.js b/WebContent/OSRM.Geocoder.js index bc1a6f14e..6896d702c 100644 --- a/WebContent/OSRM.Geocoder.js +++ b/WebContent/OSRM.Geocoder.js @@ -60,7 +60,7 @@ _onclickResult: function(marker_id, lat, lon) { OSRM.G.markers.route[index].show(); OSRM.G.markers.route[index].centerView(); - OSRM.Routing.getRoute(OSRM.C.FULL_DESCRIPTION); + OSRM.Routing.getRoute(); }, diff --git a/WebContent/OSRM.Map.js b/WebContent/OSRM.Map.js index 91a4740ab..727ad35aa 100644 --- a/WebContent/OSRM.Map.js +++ b/WebContent/OSRM.Map.js @@ -122,7 +122,7 @@ init: function() { }, // map event handlers -zoomed: function(e) { OSRM.Routing.getRoute(OSRM.C.FULL_DESCRIPTION); }, +zoomed: function(e) { OSRM.Routing.getRoute(); }, contextmenu: function(e) {;}, mousemove: function(e) {;}, click: function(e) { @@ -131,13 +131,13 @@ click: function(e) { OSRM.Geocoder.updateAddress( OSRM.C.SOURCE_LABEL, OSRM.C.DO_FALLBACK_TO_LAT_LNG ); OSRM.G.markers.route[index].show(); OSRM.G.markers.route[index].centerView( OSRM.G.map.getZoom() ); - OSRM.Routing.getRoute( OSRM.C.FULL_DESCRIPTION ); + OSRM.Routing.getRoute(); } else if( !OSRM.G.markers.hasTarget() ) { var index = OSRM.G.markers.setTarget( e.latlng ); OSRM.Geocoder.updateAddress( OSRM.C.TARGET_LABEL, OSRM.C.DO_FALLBACK_TO_LAT_LNG ); OSRM.G.markers.route[index].show(); OSRM.G.markers.route[index].centerView( OSRM.G.map.getZoom() ); - OSRM.Routing.getRoute( OSRM.C.FULL_DESCRIPTION ); + OSRM.Routing.getRoute(); } } }; \ No newline at end of file diff --git a/WebContent/OSRM.Markers.js b/WebContent/OSRM.Markers.js index 71ae6f7d2..f7395ff5e 100644 --- a/WebContent/OSRM.Markers.js +++ b/WebContent/OSRM.Markers.js @@ -105,12 +105,13 @@ onClick: function(e) { } } - OSRM.Routing.getRoute(OSRM.C.FULL_DESCRIPTION); + OSRM.Routing.getRoute(); OSRM.G.markers.highlight.hide(); }, onDrag: function(e) { this.parent.setPosition( e.target.getLatLng() ); - OSRM.Routing.getRoute(OSRM.C.NO_DESCRIPTION); + if(OSRM.G.markers.route.length>1) + OSRM.Routing.getDragRoute(); OSRM.Geocoder.updateLocation( this.parent.label ); }, onDragStart: function(e) { @@ -130,7 +131,7 @@ onDragStart: function(e) { onDragEnd: function(e) { OSRM.G.dragging = false; this.parent.setPosition( e.target.getLatLng() ); - OSRM.Routing.getRoute(OSRM.C.FULL_DESCRIPTION); + OSRM.Routing.getRoute(); if (OSRM.G.route.isShown()) { OSRM.G.route.hideOldRoute(); OSRM.G.route.hideUnnamedRoute(); diff --git a/WebContent/OSRM.Routing.js b/WebContent/OSRM.Routing.js index 1f330fea8..9ef99968c 100644 --- a/WebContent/OSRM.Routing.js +++ b/WebContent/OSRM.Routing.js @@ -70,13 +70,13 @@ showRouteSimple: function(response) { OSRM.Routing.showRouteGeometry(response); OSRM.Routing.showRouteDescriptionSimple(response); } - OSRM.Routing.updateHints(response); + OSRM.Routing._updateHints(response); -// // TODO: hack to process final drag event, if it was fenced, but we are still dragging (alternative approach) -// if(OSRM.G.pending) { -// clearTimeout(OSRM.G.pendingTimer); -// OSRM.G.pendingTimer = setTimeout(OSRM.Routing.timeoutDrag,100); -// } + // TODO: hack to process final drag event, if it was fenced, but we are still dragging (alternative approach) + if(OSRM.G.pending) { + //clearTimeout(OSRM.G.pendingTimer); + OSRM.G.pendingTimer = setTimeout(OSRM.Routing.draggingTimeout,1); + } }, showRoute: function(response) { if(!response) @@ -91,16 +91,16 @@ showRoute: function(response) { OSRM.Routing.showRouteGeometry(response); OSRM.Routing.showRouteNonames(response); OSRM.Routing.showRouteDescription(response); - OSRM.Routing.snapRoute(); + OSRM.Routing._snapRoute(); } - OSRM.Routing.updateHints(response); + OSRM.Routing._updateHints(response); }, // show route geometry showNoRouteGeometry: function() { var positions = []; - for(var i=0; i - + + + + + @@ -88,14 +92,14 @@ or see http://www.gnu.org/licenses/agpl.txt. - - + + - - + +
Start:ZeigenZeigen
Ende:ZeigenZeigen
@@ -103,8 +107,8 @@ or see http://www.gnu.org/licenses/agpl.txt.
- - + +
Reset Umdrehen Reset Umdrehen
@@ -112,7 +116,7 @@ or see http://www.gnu.org/licenses/agpl.txt.
Options
- Unbenannte Straßen hervorheben + Unbenannte Straßen hervorheben
diff --git a/WebContent/main.js b/WebContent/main.js index a7140c69f..0b4eaf714 100644 --- a/WebContent/main.js +++ b/WebContent/main.js @@ -159,6 +159,6 @@ OSRM.checkURL = function(){ } // compute route - OSRM.Routing.getRoute(OSRM.C.FULL_DESCRIPTION); + OSRM.Routing.getRoute(); } }; \ No newline at end of file diff --git a/WebContent/routing/OSRM.Routing.js b/WebContent/routing/OSRM.Routing.js new file mode 100644 index 000000000..ed5b8fd8e --- /dev/null +++ b/WebContent/routing/OSRM.Routing.js @@ -0,0 +1,148 @@ +/* +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU AFFERO General Public License as published by +the Free Software Foundation; either version 3 of the License, or +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +or see http://www.gnu.org/licenses/agpl.txt. +*/ + +// OSRM routing +// [management of routing requests and processing of responses] + +// some variables +OSRM.GLOBALS.route = null; +OSRM.GLOBALS.markers = null; + +OSRM.GLOBALS.dragging = null; +OSRM.GLOBALS.dragid = null; +OSRM.GLOBALS.pending = false; +OSRM.GLOBALS.pendingTimer = null; + + +OSRM.Routing = { + +// init routing data structures +init: function() { + OSRM.G.route = new OSRM.Route(); + OSRM.G.markers = new OSRM.Markers(); +}, + + +// -- JSONP processing -- + +// process JSONP response of routing server +timeoutRouteSimple: function() { + OSRM.RoutingGeometry.showNA(); + OSRM.RoutingDescription.showNA( OSRM.loc("TIMED_OUT") ); +}, +timeoutRoute: function() { + OSRM.RoutingGeometry.showNA(); + OSRM.RoutingNoNames.showNA(); + OSRM.RoutingDescription.showNA( OSRM.loc("TIMED_OUT") ); +}, +showRouteSimple: function(response) { + if(!response) + return; + if( !OSRM.G.dragging ) // prevent simple routing when no longer dragging + return; + + if( response.status == 207) { + OSRM.RoutingGeometry.showNA(); + OSRM.RoutingDescription.showNA( OSRM.loc("YOUR_ROUTE_IS_BEING_COMPUTED") ); + } else { + OSRM.RoutingGeometry.show(response); + OSRM.RoutingDescription.showSimple(response); + } + OSRM.Routing._updateHints(response); + + if(OSRM.G.pending) + OSRM.G.pendingTimer = setTimeout(OSRM.Routing.draggingTimeout,1); +}, +showRoute: function(response) { + if(!response) + return; + + OSRM.G.via_points = response.via_points.slice(0); + if(response.status == 207) { + OSRM.RoutingGeometry.showNA(); + OSRM.RoutingNoNames.showNA(); + OSRM.RoutingDescription.showNA( OSRM.loc("NO_ROUTE_FOUND") ); + } else { + OSRM.RoutingGeometry.show(response); + OSRM.RoutingNoNames.show(response); + OSRM.RoutingDescription.show(response); + OSRM.Routing._snapRoute(); + } + OSRM.Routing._updateHints(response); +}, + + + +//-- main function -- + +//generate server calls to query routes +getRoute: function() { + + // if source or target are not set -> hide route + if( OSRM.G.markers.route.length < 2 ) { + OSRM.G.route.hideRoute(); + return; + } + + OSRM.JSONP.call(OSRM.Routing._buildCall()+'&instructions=true', OSRM.Routing.showRoute, OSRM.Routing.timeoutRoute, OSRM.DEFAULTS.JSONP_TIMEOUT, 'route'); +}, +getDragRoute: function() { + OSRM.G.pending = !OSRM.JSONP.call(OSRM.Routing._buildCall()+'&instructions=false', OSRM.Routing.showRouteSimple, OSRM.Routing.timeoutRouteSimple, OSRM.DEFAULTS.JSONP_TIMEOUT, 'dragging');; +}, +draggingTimeout: function() { + OSRM.G.markers.route[OSRM.G.dragid].hint = null; + OSRM.Routing.getDragRoute(); +}, + +_buildCall: function() { + var source = OSRM.DEFAULTS.HOST_ROUTING_URL; + source += '?z=' + OSRM.G.map.getZoom() + '&output=json&geomformat=cmp'; + if(OSRM.G.markers.checksum) + source += '&checksum=' + OSRM.G.markers.checksum; + for(var i=0,size=OSRM.G.markers.route.length; i'+response.ShortURL+']'; +}, +showRouteLink_TimeOut: function(){ + document.getElementById('route-prelink').innerHTML = '['+OSRM.loc("LINK_TO_ROUTE_TIMEOUT")+']'; +}, + +// handling of routing description +show: function(response) { + // compute query string + var query_string = '?rebuild=1'; + for(var i=0; i'+OSRM.loc("GET_LINK_TO_ROUTE")+']'; + + // create GPX link + var gpx_link = '['+OSRM.loc("GPX_FILE")+']'; + + // create route description + var route_desc = ""; + route_desc += ''; + + for(var i=0; i < response.route_instructions.length; i++){ + //odd or even ? + var rowstyle='results-odd'; + if(i%2==0) { rowstyle='results-even'; } + + route_desc += ''; + + route_desc += '"; + + route_desc += '"; + + route_desc += '"; + + route_desc += ""; + } + + route_desc += '
'; + route_desc += ''; + route_desc += "'; + route_desc += ''; + route_desc += response.route_instructions[i][0]; + if( i == 0 ) + route_desc += ' ' + OSRM.loc( response.route_instructions[i][6] ); + if( response.route_instructions[i][1] != "" ) { + route_desc += ' on '; + route_desc += '' + response.route_instructions[i][1] + ''; + } + //route_desc += ' for '; + route_desc += ''; + route_desc += "'; + if( i != response.route_instructions.length-1 ) + route_desc += ''+OSRM.Utils.metersToDistance(response.route_instructions[i][2])+''; + route_desc += "
'; + headline = ""; + headline += OSRM.loc("ROUTE_DESCRIPTION")+":
"; + headline += '
'; + headline += "" + + OSRM.loc("DISTANCE")+": " + OSRM.Utils.metersToDistance(response.route_summary.total_distance) + + "
" + + OSRM.loc("DURATION")+": " + OSRM.Utils.secondsToTime(response.route_summary.total_time) + + "
"; + headline += '
'; + headline += '
'+route_link+'
'+gpx_link+'
'; + + var output = ""; + output += route_desc; + + document.getElementById('information-box-headline').innerHTML = headline; + document.getElementById('information-box').innerHTML = output; +}, + +// simple description +showSimple: function(response) { + headline = OSRM.loc("ROUTE_DESCRIPTION")+":
"; + headline += "" + + OSRM.loc("DISTANCE")+": " + OSRM.Utils.metersToDistance(response.route_summary.total_distance) + + "
" + + OSRM.loc("DURATION")+": " + OSRM.Utils.secondsToTime(response.route_summary.total_time) + + "
"; + headline += '

'; + + document.getElementById('information-box-headline').innerHTML = headline; + document.getElementById('information-box').innerHTML = "

"+OSRM.loc("YOUR_ROUTE_IS_BEING_COMPUTED")+".

"; +}, + +// no description +showNA: function( display_text ) { + headline = OSRM.loc("ROUTE_DESCRIPTION")+":
"; + headline += "" + + OSRM.loc("DISTANCE")+": N/A" + + "
" + + OSRM.loc("DURATION")+": N/A" + + "
"; + headline += '

'; + + document.getElementById('information-box-headline').innerHTML = headline; + document.getElementById('information-box').innerHTML = "

"+display_text+".

"; +}, + +// map driving instructions to icons +// [TODO: language-safe implementation] +getDirectionIcon: function(name) { + var directions = { + "Turn left":"turn-left.png", + "Turn right":"turn-right.png", + "U-Turn":"u-turn.png", + "Head":"continue.png", + "Continue":"continue.png", + "Turn slight left":"slight-left.png", + "Turn slight right":"slight-right.png", + "Turn sharp left":"sharp-left.png", + "Turn sharp right":"sharp-right.png", + "Enter roundabout and leave at first exit":"round-about.png", + "Enter roundabout and leave at second exit":"round-about.png", + "Enter roundabout and leave at third exit":"round-about.png", + "Enter roundabout and leave at fourth exit":"round-about.png", + "Enter roundabout and leave at fifth exit":"round-about.png", + "Enter roundabout and leave at sixth exit":"round-about.png", + "Enter roundabout and leave at seventh exit":"round-about.png", + "Enter roundabout and leave at eighth exit":"round-about.png", + "Enter roundabout and leave at nineth exit":"round-about.png", + "Enter roundabout and leave at tenth exit":"round-about.png", + "Enter roundabout and leave at one of the too many exit":"round-about.png", + "You have reached your destination":"target.png" + }; + + if( directions[name] ) + return directions[name]; + else + return "default.png"; +} + +}; \ No newline at end of file diff --git a/WebContent/routing/OSRM.RoutingGUI.js b/WebContent/routing/OSRM.RoutingGUI.js new file mode 100644 index 000000000..ea5329270 --- /dev/null +++ b/WebContent/routing/OSRM.RoutingGUI.js @@ -0,0 +1,94 @@ +/* +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU AFFERO General Public License as published by +the Free Software Foundation; either version 3 of the License, or +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +or see http://www.gnu.org/licenses/agpl.txt. +*/ + +// OSRM routing +// [handles GUI events] + + +OSRM.RoutingGUI = { + +// click: button "reset" +resetRouting: function() { + document.getElementById('input-source-name').value = ""; + document.getElementById('input-target-name').value = ""; + + OSRM.G.route.hideAll(); + OSRM.G.markers.removeAll(); + OSRM.G.markers.highlight.hide(); + + document.getElementById('information-box').innerHTML = ""; + document.getElementById('information-box-headline').innerHTML = ""; + + OSRM.JSONP.reset(); +}, + +// click: button "reverse" +reverseRouting: function() { + // invert input boxes + var tmp = document.getElementById("input-source-name").value; + document.getElementById("input-source-name").value = document.getElementById("input-target-name").value; + document.getElementById("input-target-name").value = tmp; + + // invert route + OSRM.G.markers.route.reverse(); + if(OSRM.G.markers.route.length == 1) { + if(OSRM.G.markers.route[0].label == OSRM.C.TARGET_LABEL) { + OSRM.G.markers.route[0].label = OSRM.C.SOURCE_LABEL; + OSRM.G.markers.route[0].marker.setIcon( new L.Icon('images/marker-source.png') ); + } else if(OSRM.G.markers.route[0].label == OSRM.C.SOURCE_LABEL) { + OSRM.G.markers.route[0].label = OSRM.C.TARGET_LABEL; + OSRM.G.markers.route[0].marker.setIcon( new L.Icon('images/marker-target.png') ); + } + } else if(OSRM.G.markers.route.length > 1){ + OSRM.G.markers.route[0].label = OSRM.C.SOURCE_LABEL; + OSRM.G.markers.route[0].marker.setIcon( new L.Icon('images/marker-source.png') ); + + OSRM.G.markers.route[OSRM.G.markers.route.length-1].label = OSRM.C.TARGET_LABEL; + OSRM.G.markers.route[OSRM.G.markers.route.length-1].marker.setIcon( new L.Icon('images/marker-target.png') ); + } + + // recompute route + if( OSRM.G.route.isShown() ) { + OSRM.Routing.getRoute(); + OSRM.G.markers.highlight.hide(); + } else { + document.getElementById('information-box').innerHTML = ""; + document.getElementById('information-box-headline').innerHTML = ""; + } +}, + +// click: button "show" +showMarker: function(marker_id) { + if( OSRM.JSONP.fences["geocoder_source"] || OSRM.JSONP.fences["geocoder_target"] ) + return; + + if( marker_id == OSRM.C.SOURCE_LABEL && OSRM.G.markers.hasSource() ) + OSRM.G.markers.route[0].centerView(); + else if( marker_id == OSRM.C.TARGET_LABEL && OSRM.G.markers.hasTarget() ) + OSRM.G.markers.route[OSRM.G.markers.route.length-1].centerView(); +}, + + +// changed: any inputbox (is called when return is pressed [after] or focus is lost [before]) +inputChanged: function(marker_id) { + if( marker_id == OSRM.C.SOURCE_LABEL) + OSRM.Geocoder.call(OSRM.C.SOURCE_LABEL, document.getElementById('input-source-name').value); + else if( marker_id == OSRM.C.TARGET_LABEL) + OSRM.Geocoder.call(OSRM.C.TARGET_LABEL, document.getElementById('input-target-name').value); +} + +}; \ No newline at end of file diff --git a/WebContent/routing/OSRM.RoutingGeometry.js b/WebContent/routing/OSRM.RoutingGeometry.js new file mode 100644 index 000000000..adfdca2e1 --- /dev/null +++ b/WebContent/routing/OSRM.RoutingGeometry.js @@ -0,0 +1,71 @@ +/* +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU AFFERO General Public License as published by +the Free Software Foundation; either version 3 of the License, or +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +or see http://www.gnu.org/licenses/agpl.txt. +*/ + +// OSRM routing geometry +// [renders routing geometry] + + +OSRM.RoutingGeometry = { + +// show route geometry - if there is a route +show: function(response) { + var geometry = OSRM.RoutingGeometry._decode(response.route_geometry, 5); + + var positions = []; + for( var i=0, size=geometry.length; i < size; i++) + positions.push( new L.LatLng(geometry[i][0], geometry[i][1]) ); + + OSRM.G.route.showRoute(positions, OSRM.Route.ROUTE); +}, + +//show route geometry - if there is no route +showNA: function() { + var positions = []; + for(var i=0, size=OSRM.G.markers.route.length; i= 0x20); + var dlat = ((result & 1) ? ~(result >> 1) : (result >> 1)); + lat += dlat; + shift = 0; + result = 0; + do { + b = encoded.charCodeAt(index++) - 63; + result |= (b & 0x1f) << shift; + shift += 5; + } while (b >= 0x20); + var dlng = ((result & 1) ? ~(result >> 1) : (result >> 1)); + lng += dlng; + array.push([lat * precision, lng * precision]); + } + return array; +} + +}; \ No newline at end of file diff --git a/WebContent/routing/OSRM.RoutingNoNames.js b/WebContent/routing/OSRM.RoutingNoNames.js new file mode 100644 index 000000000..1d67dac0b --- /dev/null +++ b/WebContent/routing/OSRM.RoutingNoNames.js @@ -0,0 +1,68 @@ +/* +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU AFFERO General Public License as published by +the Free Software Foundation; either version 3 of the License, or +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +or see http://www.gnu.org/licenses/agpl.txt. +*/ + +// OSRM routing +// [renders route segments that are unnamed streets] + + +OSRM.RoutingNoNames = { + +// displays route segments that are unnamed streets +show: function(response) { + // do not display unnamed streets? + if( document.getElementById('option-highlight-nonames').checked == false) { + OSRM.G.route.hideUnnamedRoute(); + return; + } + + // mark geometry positions where unnamed/named streets switch + var named = []; + for (var i = 0; i < response.route_instructions.length; i++) { + if( response.route_instructions[i][1] == '' ) + named[ response.route_instructions[i][3] ] = false; // no street name + else + named[ response.route_instructions[i][3] ] = true; // yes street name + } + + // aggregate geometry for unnamed streets + var geometry = OSRM.RoutingGeometry._decode(response.route_geometry, 5); + var is_named = true; + var current_positions = []; + var all_positions = []; + for( var i=0; i < geometry.length; i++) { + current_positions.push( new L.LatLng(geometry[i][0], geometry[i][1]) ); + + // still named/unnamed? + if( (named[i] == is_named || named[i] == undefined) && i != geometry.length-1 ) + continue; + + // switch between named/unnamed! + if(is_named == false) + all_positions.push( current_positions ); + current_positions = []; + current_positions.push( new L.LatLng(geometry[i][0], geometry[i][1]) ); + is_named = named[i]; + } + + // display unnamed streets + OSRM.G.route.showUnnamedRoute(all_positions); +}, + +showNA: function() { + OSRM.G.route.hideUnnamedRoute(); +} +}; \ No newline at end of file