Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
function togglePopup(id, childs) { 	var next = $(id).is(":hidden"); 	childs.push(id); 	childs.forEach(function (i) { if (next) {$(i).show();} else {$(i).hide();} }); }  function escapeHtml(text) {   var escapedText = {     '&': '&a;',     //'"': '&q;', // this should be fine, we don't do eval     //'\'': '&s;',     '<': '&l;',     '>': '&g;',   };   //return text.replace(/[&"'<>]/g, function(s) {return escapedText[s];});   return text.replace(/[&<>]/g, function(s) {return escapedText[s];}); }  function getArticleCoords() { 	// try to use {{geo}} 	var zoom = 13; 	var lat = RLCONF['wgCoordinates']['lat']; 	var lon = RLCONF['wgCoordinates']['lon']; 	// override by first mapframe 	if ($('.mw-kartographer-map').length > 0) { 		var firstmap = $('.mw-kartographer-map')[0]; 		var v; 		v = firstmap.getAttribute('data-lat'); 		if (v != null) 			lat = v; 		v = firstmap.getAttribute('data-lon'); 		if (v != null) 			lon = v; 		v = firstmap.getAttribute('data-zoom'); 		if (v != null) 			zoom = v; 	} 	return [lat, lon, zoom]; } 		 $(document).ready( function () { 	maptoolStr='\ 	<table id="maptool" style="display: none; border: 1px solid black; width: 100%;background-color: #eee;"><tbody>\ <tr><td colspan="2">Show:\     <input type="checkbox" id="wd-map" checked="" disabled title="Show map with the items.">\     <label for="wd-map">map</label>\     (<input type="checkbox" id="wd-map-resizable" title="Enable resize handle for the map">\     <label for="wd-map-resizable">resizable</label>) \     <input type="checkbox" id="wd-table" checked="" title="Show a table containing the found data. If Wikipedia language is specified, also the respective wikipedia articles in that language.">\     <label for="wd-table">table</label>\ </td></tr>\ <tr><td colspan="2" style="border-bottom: 1px solid black"><b>Query area:</b>\     <br/><span style="white-space: nowrap"><input type="radio" id="query-radius" name="query-type" checked /><label for="query-radius">Radius/km:</label>\     <input type="text" id="query-radius-km" value="10" style="width: 5em; box-sizing: border-box" title="Radius." />, center:<input type="text" id="query-radius-center" style="width: 20em; box-sizing: border-box" title="map center (lat,long)" /></span>\     <br/><span style="white-space: nowrap"><input type="radio" id="query-area" name="query-type" /><label for="query-area">Area:</label>\     SW:<input type="text" id="query-sw" style="width: 20em; box-sizing: border-box" title="SW corner (lat,long)" />\     NE:<input type="text" id="query-ne" style="width: 20em; box-sizing: border-box" title="NE corner (lat,long)" /></span>\ </td></tr>\ <tr style="vertical-align:  top;"><td id="wd-cfg" style="border-right: 1px solid #ccc; padding: 0.5em; width: 50%">\     <h3><input type="checkbox" id="wd-enable" checked><label for="wd-enable">Wikidata</label></h3>\     <label for="wd-language">Wikipedia language:</label><input type="text" id="wd-language" class="wd-input" value="en" style="width: 5em; box-sizing: border-box" title="Enter wikipedia language shortcut (two or three letters). If left empty, just wikidata items are searched, with or without wikipedia articles.">\     <br /><input type="checkbox" id="wd-sort-views" checked="" title="If checked AND wikipedia article is found (see above), the average number of views in the past months is retrieved, and used to sort the items (descending)."><label for="wd-sort-views">Sort by wikipedia viewcount</label>\ \     <br/><br/><div style="margin-left: 1em; margin-left: 1em; background: #dddddd; padding: 0.25em;">\         <b>Filters</b><br/><input type="checkbox" class="wd-input" id="wd-filter-religious" title="Show religious buildings"><label for="wd-filter-religious">religious</label>\         <br><input type="checkbox" class="wd-input" id="wd-filter-settlements" title="Show human settlements buildings"><label for="wd-filter-settlements">settlements</label>\         <br><label for="wd-filter">SPARQL:</label><input type="text" id="wd-filter" class="wd-input" value="MINUS{?place wdt:P31/wdt:P279* wd:Q3839081}" style="width: 100%;box-sizing: border-box" title="Filters wikidata using also this SPARQL query - make sure the syntax is correct, if not empty. The default/example filters out all disaster events."></div>\ </td><td id="osm-cfg" style="padding: 0.5em">\     <h3><input type="checkbox" id="osm-enable"><label for="osm-enable"> OpenStreetMap</label></h3>\     <div style="margin-left: 1em; margin-left: 1em; background: #dddddd; padding: 0.25em;">\         <b>Filters</b><br/><input type="checkbox" id="osm-filter-viewpoint" checked=""><label for="osm-filter-viewpoint">viewpoint</label>\         <br><input type="checkbox" id="osm-filter-historic" checked=""><label for="osm-filter-historic">historic</label>\         <br><input type="checkbox" id="osm-filter-museum" checked=""><label for="osm-filter-museum">museum</label>\         <br><label for="osm-filter">AUX:</label><input type="text" id="osm-filter" value="[\'tourism\'~\'attraction\']" style="width: 100%;box-sizing: border-box" title="Filters OSM also uing this tags - make sure the syntax is correct, if not empty.">\     </div>\ </td></tr>\ \ <tr><td class="voy-coord-indicator" style="background: white">\     <button class="voy-map-globe-js" style="display: inline; cursor: pointer;" title="Click to open or close the map of Ruzomberok">Query and show</button>\     <span id="mapframe-size"></span> \ </td><td id="mapframe-info" style="text-align: right; background: white"></td></tr>\ </tbody></table>\ 	'; 	 	if ('wgCoordinates' in RLCONF) { 		var coords = getArticleCoords();  		$('.mw-indicators').prepend(     	'<span id="maptool-button" onclick="togglePopup(\'#maptool\', [\'#maptool-listings\', \'#voy-topMap\'])"> \     		<span style="display: inline; cursor: pointer;"> \     			<img src="https://upload.wikimedia.org/wikipedia/commons/thumb/f/ff/Wikidata-logo.svg/32px-Wikidata-logo.svg.png"/> \     	</span></span>'     	);     	$("#contentSub").append(maptoolStr);     	$("#query-radius-center")[0].value = coords[0] + "," + coords[1];     	$("#wd-map-resizable").change(function() {     		$("#voy-topMap").css("resize", (this.checked ? "both" : "none"));});     	     	function enableForm(chkbox) 		{ 		    chkbox.parent().parent().find('input').not(chkbox).prop( 		        'disabled', !$(chkbox).prop('checked') 		    ); 		} 		enableForm($('#osm-enable')) 	    $('#osm-enable').change(function() { enableForm($(this)); }); 	    enableForm($('#wd-enable')) 	    $('#wd-enable').change(function() { enableForm($(this)); }); 	} } );  //<nowiki> /*****************************************************************************  * mapTools v2.0, 2023-06-16  * Several map creation and supporting tools  * Original author: Roland Unger  * Support of desktop and mobile views  * Documentation: https://de.wikivoyage.org/wiki/Wikivoyage:Gadget-MapTools.js  * License: GPL-2.0+, CC-by-sa 3.0  ****************************************************************************/ /* eslint-disable mediawiki/class-doc */  ( function( $, mw ) { 	'use strict';  	var mapTools = function() {  		// https://www.mediawiki.org/wiki/Help:Extension:Kartographer/Icons 		const wdMakiMap = {     		"Q39816": "mountain",     		"Q8502": "mountain",     		"Q46831": "mountain",     		"Q43501": "zoo",     		"Q515": "city",     		"Q532": "village",     		"Q3957": "town",     		"Q2983893": "city", // quarter     		"Q40080": "beach",     		"Q44782": "harbor",     		"Q8072": "volcano",     		"Q3848936": "park", // protected area     		"Q473972": "park", // protected landscape     		"Q46169": "park", // national park     		"Q22746": "park", // urban park     		"Q23397": "water", // lake     		"Q35509": "tunnel",     		"Q34038": "waterfall",     		"Q16970": "religious-christian",     		"Q33506": "museum",     		"Q5487333": "beer", // microbrewery     		"Q131734": "beer", // brewery     		"Q4989906": "monument",     		"Q179700": "monument", // statue     		"Q6017969": "viewpoint",     		"Q12323": "dam",     		"Q751876": "castle",     		"Q483110": "stadium",     		"Q1007870": "art-gallery",     		"Q2281788": "aquarium",     		"Q45782": "aquarium",     		"Q4421": "natural", // forest     		"Q4022": "water", // river     		"Q55490": "rail", // through station     		"Q55488": "rail", // railway station     		"Q1268865": "rail", // light rail     		"Q3914": "school",     		"Q23413": "castle",     		"Q11166728": "communications-tower",     		"Q1798641": "communications-tower",     		"Q22698": "park",     		"Q24354": "theatre",     		"Q1060829": "theatre", // concert hall     		"Q108325": "religious-christian", // church     		"Q317557": "religious-christian", // parish church     		"Q1129743": "religious-christian", // filial church     		"Q56242275": "religious-christian", // lutheran church     		"Q623525": "religious-christian", // rotunda     		"Q131681": "water", // reservoir     		"Q34627": "religious-jewish", // synagogue     		"Q47521": "water", // stream     		"Q2977": "place-of-worship", // cathedral     		"Q1802963": "home", // cathedral 		};  		// technical constants 		const maxZoomLevel = 19, 			defaultMaplinkZoomLevel = 17, 			defaultMapZoomLevel = 14,  			defaultProperties = { 				'stroke-width': 2, 				'fill-opacity': 0.5 			},  			indicatorSelector = '.voy-coord-indicator', 			indicatorCoordsSelector = '.voy-coords a', 			indicatorGlobeImgSrc = 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6d/Earth_-_The_Noun_Project.svg/20px-Earth_-_The_Noun_Project.svg.png', 			indicatorMapContainerId = 'voy-topMap',  			fullScreenContainerId = 'voy-fullScreenMap',  			articlesMapId = 'voy-articles-map', 			useArticlesMap = true,  			mapframeContainerSelector = '.mw-kartographer-container', 			mapframeMapSelector = '.mw-kartographer-map',  			markerSelector = '.vcard', // wrapper selector of a single marker or listing 			kartographerSelector = '.mw-kartographer-maplink', 			nameClass = 'listing-name', 			imageClass = 'listing-image',  			footCaptionSelector = '.oo-ui-windowManager-fullscreen .mw-kartographer-captionfoot', 			captionMarkerClass = 'voy-caption-marker', 			captionInverseMarkerClass = 'voy-caption-marker-invers',  			dataLat = 'data-lat', 			dataLon = 'data-lon', 			dataZoom = 'data-zoom', 			dataName = 'data-name', 			dataColor = 'data-color', 			dataSymbol = 'data-symbol', 			dataNumber = 'data-number', 			dataGroup = 'data-group-translated', // other wikis: 'data-type' 			dataDialog = 'data-dialog', 			dataHeight = 'data-height', 			dataOverlays = 'data-overlays', 			fallbackLang = 'en'; 		 		// strings depending on page content language 		const wikiStrings = { 			de: { 				defaultShow:      '["Maske","Track","Aktivität","Anderes","Anreise","Ausgehen","Aussicht","Besiedelt","Fehler","Gebiet","Gesundheit","Kaufen","Küche","Natur","Religion","Sehenswert","Unterkunft","aquamarinblau","cosmos","gold","hellgrün","orange","pflaumenblau","rot","silber","violett"]', 				defaultGroupName: 'Karte', 				mask:             'Maske', 				track:            'Track' 			}, 			en: { 				defaultShow:      '["mask","around","buy","city","do","drink","eat","go","listing","other","see","sleep","vicinity","view","black","blue","brown","chocolate","forestgreen","gold","gray","grey","lime","magenta","maroon","mediumaquamarine","navy","orange","plum","purple","red","royalblue","silver","steelblue","teal"]', 				defaultGroupName: 'map', 				mask:             'mask', 				track:            'track' 			}, 			es: { 				defaultShow:      '["máscara","sendero","área","beber","comer","comprar","dormir","error","habitadas","hacer","ir","otro","ver","vista","aguamarina","ciruela","cosmos","oro","lima","naranja","violeta","plata","rojo"]', 				defaultGroupName: 'mapa', 				mask:             'máscara', 				track:            'sendero' 			}, 			fr: { 				defaultShow:      '["aller","destination","diplomatie","loger","manger","sortir","ville","voir","mask","around","buy","city","do","drink","eat","go","listing","other","see","sleep","vicinity","view","black","blue","brown","chocolate","forestgreen","gold","gray","grey","lime","magenta","maroon","mediumaquamarine","navy","orange","plum","purple","red","royalblue","silver","steelblue","teal"]', 				defaultGroupName: 'carte', 				mask:             'mask', 				track:            'piste' 			}, 			it: { 				defaultShow:      '["mask","around","buy","city","do","drink","eat","go","listing","other","see","sleep","vicinity","view","black","blue","brown","chocolate","forestgreen","gold","gray","grey","lime","magenta","maroon","mediumaquamarine","navy","orange","plum","purple","red","royalblue","silver","steelblue","teal"]', 				defaultGroupName: 'mappa', 				mask:             'mask', 				track:            'traccia' 			} 		};  		// strings depending on user language 		const userStrings = { 			de: { 				articlesMapTitle:     'Übersicht der Wikivoyage-Artikel', 				closeButtonTitle:     'Schließen', 				indicatorActionLabel: 'Karte', 				indicatorButtonTitle: 'Klick öffnet oder schließt die Karte für $1', 				magnifyButtonTitle:   'Karte vergrößern', 				mapCenter:            'Kartenzentrum', 				mapOf:                'Karte von $1' 			}, 			en: { 				articlesMapTitle:     'Summary of Wikivoyage articles', 				closeButtonTitle:     'Close', 				indicatorActionLabel: 'Map', 				indicatorButtonTitle: 'Click to open or close the map of $1', 				magnifyButtonTitle:   'Enlarge map', 				mapCenter:            'Map center', 				mapOf:                'Map of $1' 			}, 			es: { 				articlesMapTitle:     'Resumen de los artículos de Wikivoyage', 				closeButtonTitle:     'Cerrar', 				indicatorActionLabel: 'Mapa', 				indicatorButtonTitle: 'Haga clic para abrir o cerrar el mapa de $1', 				magnifyButtonTitle:   'Aumentar mapa', 				mapCenter:            'Centro del mapa', 				mapOf:                'Mapa de $1' 			}, 			fr: { 				articlesMapTitle:     'Résumé des articles de Wikivoyage', 				closeButtonTitle:     'Fermer', 				indicatorActionLabel: 'Carte', 				indicatorButtonTitle: 'Cliquez pour ouvrir ou fermer le carte de $1', 				magnifyButtonTitle:   'Agrandir la carte', 				mapCenter:            'Centre de la carte', 				mapOf:                'Carte de $1' 			}, 			it: { 				articlesMapTitle:     'Sommario degli articoli di Wikivoyage', 				closeButtonTitle:     'Chiudi', 				indicatorActionLabel: 'Mappa', 				indicatorButtonTitle: 'Clicca per aprire o chiudere la mappa di $1', 				magnifyButtonTitle:   'Ingrandisci mappa', 				mapCenter:            'Centro mappa', 				mapOf:                'Mappa di $1' 			} 		};  		// internal use 		const ver = '2023-03-29', 			$body = $( 'body' ), 			pageLang = mw.config.get( 'wgPageContentLanguage' ), 			userLang = mw.config.get( 'wgUserLanguage' ), 			pageTitle = mw.config.get( 'wgTitle' ), 			articlePath = mw.config.get( 'wgArticlePath' ), 			thumbPath = '//upload.wikimedia.org/wikipedia/commons/thumb/', 			scriptUrl = mw.format( 'https://wikivoyage.toolforge.org/w/data/$1-articles.js', pageLang ), 			isMinerva = mw.config.get( 'skin' ) === 'minerva'; // mobile view 		var defaultShowArray, 			messages = {};  		// storing prune cluster library 		var	pruneClusterLib;  		// storing GeoJSON data 		var data = {}; 		var wikidataResponse = null; 		var osmResponse = null; 		var mapHandle;  		// array of objects: { name: group.name, attribution: attributions } 		var groups = [];  		// copying translation strings to messages depending on chain languages 		function addMessages( strings, chain ) { 			for ( var i = chain.length - 1; i >= 0; i-- ) { 				if ( strings.hasOwnProperty( chain[ i ] ) ) { 					$.extend( messages, strings[ chain[ i ] ] ); 				} 			} 		}  		// copying translation strings to messages 		function setupMessages() { 			addMessages( wikiStrings, [ pageLang, fallbackLang ] ); 			const chain = ( userLang == pageLang ) ? [ pageLang, fallbackLang ] : 				[ userLang, pageLang, fallbackLang ]; 			addMessages( userStrings, chain ); 		}  		// creating a Kartographer map 		function createMap( id, center, zoom, caption, options, color, isInvers ) { 			mw.loader.using( [ 'ext.kartographer.box' ] ).then( function() { 				var $id = $( '#' + id ), 					group, i, j, layerOptions;  				// for simple full-screen map 				if ( !options.withDialog && options.isFullScreen ) { 					$body.css( { overflow: 'hidden' } ); 					$id.css( { position: 'fixed', height: '100%', width: '100%', 						top: 0, left: 0, 'z-index': 101 } ); // vector skin 				}			  				// creating base map  				// fortunately ext.kartographer.box is not validating the 				// GeoJSON against the GeoJSON+simplestyle schema 				// as it is done by maplink/mapframe tags 				// https://github.com/mapbox/simplestyle-spec/tree/master/1.1.0 				// see also: phabricator task T181604  				var kartoBox = mw.loader.require( 'ext.kartographer.box' ); 				var map = kartoBox.map( { 					container: $id[ 0 ], 					center: center, 					zoom: zoom, 					allowFullScreen: options.allowFullScreen, 					alwaysInteractive: true, 					captionText: caption, 					fullscreen: options.isFullScreen, 					featureType: options.featureType 				} ); 				mapHandle = map; 				// following line is necessary for proper loading of 				// map-dialog sidebar 				map.initView( center, zoom ); 				// the following property is used by Kartographer.js  				if ( options.enableNearby ) { 					map.nearbyEnabled = true; 					if ( options.toggleNearby ) { 						map.toggleNearby = true; 					} 				}  				// adding markers by group names to separate layers 				if ( options.withData && groups.length ) { 					for ( i = 0; i < options.show.length; i++ ) { 						for ( j = 0; j < groups.length; j++ ) { 							group = groups[ j ]; 							if ( group.name === options.show[ i ] ) { 								layerOptions = { name: group.name }; 								if ( group.attribution !== '' ) { 									layerOptions.attribution = group.attribution; 								} 								if (data !== null) 									map.addGeoJSONLayer( data[ group.name ], layerOptions ); 								break; 							} 						} 					} 				} 				getPOIsFromWD(map); 				getPOIsFromOSM(map);  				// adding dialog to full-screen map 				if ( options.withDialog ) { 					$id.addClass( 'mw-kartographer-mapDialog-map' ); 					mw.loader.using( 'ext.kartographer.dialog' ).done( function() { 						map.doWhenReady( function() { 							require( 'ext.kartographer.dialog' ).render( map ); 						} ); 					} ); 				} else { 					// adding Close control to non-full-screen map if required 					if ( options.withClose ) { 						var controls = $( '.leaflet-top.leaflet-right', $id ), 							control = $( '<div class="leaflet-bar leaflet-control-static leaflet-control"></div>' ) 							.append( $( '<a class="voy-icon-close"></a>', 									{ title: messages.closeButtonTitle, 									role: 'button', 'aria-disabled': 'false' } ) 								.click( function() { 									$id.remove(); 									if ( options.isFullScreen ) { 										$body.css( { overflow: 'auto' } ); 									} 								} ) 							); 						controls.prepend( control ); 					}  					// adding Nearby and Layers controls using Kartographer.js 					if ( options.withControls ) { 						mw.hook( 'wikipage.maps' ).fire( map ); 					}  				} 				map.doWhenReady( function() { 					map.on('click', function(e){ 						$("#query-radius-center")[0].value = e.latlng.lat.toFixed(5) + "," + e.latlng.lng.toFixed(5); 					}); 					 					var dragf = function() {  						var bounds = map.getBounds(); 						var center = map.getCenter(); 						var zoom = map.getZoom(); 						$("#mapframe-info")[0].textContent =  							"{{mapframe|" + center.lat.toFixed(5) + "|" + center.lng.toFixed(5) + 							"|zoom=" + zoom + 							"|width=" + $("#voy-topMap").width() + 							"|height=" + $("#voy-topMap").height() + "}}"; 						$("#mapframe-size")[0].textContent =  							" (size: " + (map.distance(bounds._southWest, bounds._northEast) / 1000).toFixed(1) + "km)"; 						$("#query-sw")[0].value = bounds._southWest.lat.toFixed(5) + ',' + bounds._southWest.lng.toFixed(5); 						$("#query-ne")[0].value = bounds._northEast.lat.toFixed(5) + ',' + bounds._northEast.lng.toFixed(5); 						 						$(".voy-map-globe-js").prop("disabled", 							(map.distance(bounds._southWest, bounds._northEast) > 100000)); 					}; 					map.on('zoomend', dragf); 				    map.on('dragend', dragf);  					// remove inert attribute 					$id.removeAttr( 'inert' );  					if ( color && options.withDialog ) { 						setTimeout( function() { 							var footCaption = $( footCaptionSelector ); 							if ( footCaption.length ) { 								var	captionArray = footCaption.text().split("​:"), 									classes = captionMarkerClass + 										( isInvers ? ' ' + captionInverseMarkerClass : '' ); 								footCaption.html( mw.format( '<span class="$1" style="background-color: $2">$3</span>$4', 									classes, color, captionArray[ 0 ], captionArray[ 1 ] || '' ) ); 							} 						}, 700); 					} 				} ); 			} ); 		}  		// creating GeoJSON data separated by group 		function singleDataset( color, symbol, title, lat, lon, description, group ) { 			group = group || messages.defaultGroupName; 			if ( !data.hasOwnProperty( group ) ) { 				data[ group ] = []; 			} 		 			data[ group ].push( { 				'type': 'Feature', 				properties: { 					'marker-color': color, 					'marker-size': 'medium', 					'marker-symbol': symbol ? symbol.toLowerCase() : symbol, 					title: title, 					description: description 				}, 				geometry: { 					'type': 'Point', 					coordinates: [ lon, lat ] 				} 			} ); 		}  		function extractCoordinates(item) { 		  if (item.location && item.location.datatype === "http://www.opengis.net/ont/geosparql#wktLiteral") { 		    var match = item.location.value.match(/Point\(([^ ]+) ([^)]+)\)/); 		    if (match && match.length === 3) { 		      var lon = parseFloat(match[1].trim()); 		      var lat = parseFloat(match[2].trim()); 		      return [lon, lat]; 		    } 		  } 		  return null; 		}  		function convertWDToGeoJSON(wd) { 			var geoJSON = { 				type: "FeatureCollection", 				features: [] 			};  			var bindings = wd.results.bindings; 			for (var i = 0; i < bindings.length; i++) { 				var item = bindings[i]; 				var coordinates = extractCoordinates(item); 				 				var markerSymbol = ""; 				var typeid = ""; 				if (item.instanceOf.value) { 					typeid = item.instanceOf.value.split('/').reverse()[0]; 					if (typeid in wdMakiMap) 						markerSymbol = wdMakiMap[typeid]; 				} 	 				if (coordinates) { 				  var title = item.placeLabel ? escapeHtml(item.placeLabel.value) : "Untitled"; 				  var wdid = item.place.value.split('/').reverse()[0]; 				  var lang = $("#wd-language")[0].value; 				  var imgStr = ""; 				  if (item.image) { 				  	var img = "", imgThumb = ""; 				  	img = escapeHtml(item.image.value); 				  	//imgThumb = img.replace("/commons/", "/commons/thumb/"); 				  	//imgThumb += "320px-" + imgThumb.split('/').reverse()[0]; 				  	imgThumb = img.replace("http://", "https://"); 				  	imgStr= "<a href=\"" + img + "\">" +  				  		"<img style=\"width: 100%\" src=\"" + imgThumb + "\" />" 				  		+ "</a><br/> "; 				  } 				  var feature = { 				    type: "Feature", 				    geometry: { 				      type: "Point", 				      coordinates: coordinates 				    }, 				    properties: { 				      'marker-color': '#999999', 					  'marker-size': 'medium', 				      "marker-symbol": markerSymbol, 	  			      "articleName": item.articleTitle ? escapeHtml(item.articleTitle.value) : "", 				      "wikidataID": wdid, 				      "wikidataName": title, 				      "instanceOf": typeid, 				      title: "<a href=\"" + escapeHtml(item.place.value) + "\">" + title + " / " + wdid + "</a><br/> ", 				      description: 				        (item.placeDescription ? (escapeHtml(item.placeDescription.value) + "<br/>") : "") + 				    	(item.articleTitle ? ("<a href=\"https://" + lang + ".wikipedia.org/wiki/" + escapeHtml(item.articleTitle.value) + "\">:" + lang + ":" + escapeHtml(item.articleTitle.value) + "</a>") : "No description available") + " " + 				    	imgStr 				    } 				  }; 				 				  geoJSON.features.push(feature); 				} 			} 			 			return geoJSON; 		} 		 		function convertOSMToGeoJSON(osm) { 			var geoJSON = { 				type: "FeatureCollection", 				features: [] 			};  			var elements = osm.elements; 			for (var i = 0; i < elements.length; i++) { 				var item = elements[i]; 				var coordinates; 				if ('center' in item) { 					coordinates = [item.center.lon, item.center.lat]; 				} else { 					coordinates = [item.lon, item.lat]; 				} 				 				var markerSymbol = ""; 				if ('tourism' in item.tags && item.tags.tourism == 'viewpoint') { 					markerSymbol = 'viewpoint'; 				} else if ('tourism' in item.tags && item.tags.tourism == 'museum') { 					markerSymbol = 'museum'; 				} else if ('historic' in item.tags) { 					markerSymbol = item.tags.historic; 				}  				if (coordinates) { 				  var title = 'name' in item.tags ? escapeHtml(item.tags.name) : ""; 				  var feature = { 				    type: "Feature", 				    geometry: { 				      type: "Point", 				      coordinates: coordinates 				    }, 				    properties: { 				      'marker-color': '#9999ff', 					  'marker-size': 'medium', 				      "marker-symbol": markerSymbol, 				      title: title, 				      description: 				    	'{{listing | name=' + title + ' | lat=' + coordinates[1] + " | long=" + coordinates[0] + "}}<br/>" + 				    	'<div style="width: 250px; word-break: break-all">' + escapeHtml(JSON.stringify(item.tags)).replace(/(Q[0-9]*)/, "<a href=\"https://www.wikidata.org/wiki/$1\">$1</a>") + '</div>' 				    } 				  }; 				 				  geoJSON.features.push(feature); 				} 			} 			 			return geoJSON; 		}  		function getAverageViews(lang, articleName) { 			var d = new Date(); 			d.setMonth(-1); 			d.setDate(1); 			var to = d.toISOString().split('T')[0].replaceAll('-', ''); 			d.setMonth(-6); 			var from = d.toISOString().split('T')[0].replaceAll('-', ''); 	        var url = "https://wikimedia.org/api/rest_v1/metrics/pageviews/per-article/" + lang + ".wikipedia/all-access/all-agents/" + articleName + "/monthly/" + from + "/" + to; 	        return $.ajax({ 	            url: url, 	            method: 'GET', 	            dataType: 'json', 	        }); 	    }  		function retrieveWPViews(lang, geoJSONResult) { 			var promises = geoJSONResult.features.map(function(entry) { 	            var articleName = entry.properties.articleName; 	            if (articleName != "" && !articleName.includes('/')) 	                return getAverageViews(lang, articleName) 	                .then(function(data) { 	                    var views = data.items.map(function(item) {return item.views;}); 	                    var averageViews = views.length ? (views.reduce(function(a, b) {return (a + b);}) / views.length) : 0; 	                    averageViews = Math.ceil(averageViews); 	                    entry.properties.views = averageViews; 	                }).catch(function(error) { entry.properties.views = -1;}); 	        	});         	         	return promises; 		} 		 		function dumpListings(geoJSONResult) { 			var container = $( '#' + indicatorMapContainerId ); 			container.after('<table id="maptool-listings" border="1"><thead><tr><th>WD ID</th><th>WP name</th><th>views</th><th>symbol</th><th>listing</th></tr></thead><tbody></tbody></table>'); 			 var tbody = $('#maptool-listings')[0].tBodies[0]; 			 var lang = $("#wd-language")[0].value;  	        // Clear existing content 	        tbody.innerHTML = ''; 	 	        // Loop through items and create rows 	        geoJSONResult.features.forEach(function(item) { 	        	var lName = "| name = " + item.properties.wikidataName; 				var lAltName = ""; 				if (item.properties.wikidataName != item.properties.articleName) 					lAltName = " | alt = " + item.properties.articleName; 	            var tr = document.createElement('tr'); 				var wparticle = ( 					item.properties.articleName ? 					("<a href=\"https://" + lang + ".wikipedia.org/wiki/" + item.properties.articleName + "\">:" + lang + ":" + item.properties.articleName + "</a>") 					: "No title available"); 	            tr.innerHTML = "\ 	                <td>" + item.properties.title + "</td>\ 	                <td>" + wparticle + "</td>\ 	                <td>" + (item.properties.views ? item.properties.views : "") + "</td>\ 	                <td>" + item.properties['marker-symbol'] + " | <a href=\"https://www.wikidata.org/wiki/" + item.properties.instanceOf + "\">" + item.properties.instanceOf + "</a></td>\ 	                <td>{{listing " + lName + lAltName + " | wikidata = " + item.properties.wikidataID + "}}</td>"; 	            tbody.appendChild(tr); 	        }); 		}  		function addMarkerColors(geoJSONResult) { 			var redShade; 			var redFrom = 0xff; 			var redTo = 0x99;  			for (var i = 0; i < geoJSONResult.features.length; i++) { 				redShade = ~~((geoJSONResult.features.length - i) * (redFrom - redTo) / geoJSONResult.features.length) + redTo; 				var redShadeStr = redShade.toString(16); 				if (redShadeStr.length == 1) 					redShadeStr = "0" + redShadeStr; 				if (geoJSONResult.features[i].properties.views >= 0) 					geoJSONResult.features[i].properties['marker-color'] = '#' + redShadeStr + '9999'; 			} 		}  		function getPOIsFromOSM(map) { 			if (!osmResponse) 				return; 			var geoJSONResult = convertOSMToGeoJSON(osmResponse); 			map.addGeoJSONLayer(geoJSONResult, {name: "OSM items"}); 			/*if ($("#osm-table")[0].checked) { 				dumpListings(geoJSONResult); 			}*/ 		}  		function getWDGeoJSON(lat, lon) { 			function makeSPARQLQuery( endpointUrl, sparqlQuery ) { 				var settings = { 					headers: { Accept: 'application/sparql-results+json' }, 					data: { query: sparqlQuery } 				}; 				return $.ajax( endpointUrl, settings ); 			} 			 			var radius = $("#query-radius-km")[0].value; 			var lang = $("#wd-language")[0].value; 			var auxFilter = $("#wd-filter")[0].value; 			var wikirule = (lang !== "") ?  			  "?article schema:about ?place . \ 			  ?article schema:isPartOf <https://" + lang + ".wikipedia.org/>. \ 			  ?article schema:name ?articleTitle ." : ""; 			if (lang === "") 				lang = "en";  			if (!$("#wd-filter-religious")[0].checked) { 				auxFilter += " MINUS{?place wdt:P31/wdt:P279* wd:Q24398318} "; // religious building 			} 			if (!$("#wd-filter-settlements")[0].checked) { 				auxFilter += " MINUS{?place wdt:P31/wdt:P279? wd:Q486972} "; // human settlement 				auxFilter += " MINUS{?place wdt:P31/wdt:P279* wd:Q15284} "; // municipality 				auxFilter += " MINUS{?place wdt:P31/wdt:P279? wd:Q56061} "; // administrative division 			} 			var areaQuery; 	 			if ($("#query-radius")[0].checked) { 				areaQuery = "SERVICE wikibase:around { \    ?place wdt:P625 ?location . \    bd:serviceParam wikibase:center \"Point(" + String(lon) + "," + String(lat) + ")\"^^geo:wktLiteral . \    bd:serviceParam wikibase:radius \"" + String(radius) + "\" . \  }"; 			} else { 				var sw = $("#query-sw")[0].value.split(","); 				var ne = $("#query-ne")[0].value.split(","); 				areaQuery = "SERVICE wikibase:box { \    ?place wdt:P625 ?location . \    bd:serviceParam wikibase:cornerSouthWest \"Point(" + String(sw[1]) + "," + String(sw[0]) + ")\"^^geo:wktLiteral .\    bd:serviceParam wikibase:cornerNorthEast \"Point(" + String(ne[1]) + "," + String(ne[0]) + ")\"^^geo:wktLiteral .\  }"; 			}		  			var endpointUrl = 'https://query.wikidata.org/sparql', 				sparqlQuery = "\n" + "\ SELECT DISTINCT ?place ?placeDescription ?placeLabel ?articleTitle \ \ (SAMPLE(?location) as ?location) \ (SAMPLE(?image) AS ?image)\ (SAMPLE(?instanceOf) AS ?instanceOf)\ \ WHERE {\  " + areaQuery + auxFilter + "\  SERVICE wikibase:label { bd:serviceParam wikibase:language \"en," + lang + "\". } \   ?place wdt:P18 ?image. \   ?place wdt:P31 ?instanceOf. \   " + wikirule + "\ } \ GROUP BY ?place ?placeDescription ?placeLabel ?articleTitle \ LIMIT 200 \ ";  			return makeSPARQLQuery( endpointUrl, sparqlQuery).then(function(data){wikidataResponse = data;}); 		}  		function getPOIsFromWD(map) { 			if (!wikidataResponse) 				return; 			var geoJSONResult = convertWDToGeoJSON(wikidataResponse); 			if ($("#wd-sort-views")[0].checked) { 				var lang = $("#wd-language")[0].value; 				var promises = retrieveWPViews(lang, geoJSONResult);  				Promise.all( promises ).then( function() { 		            // Sort the table data by views in descending order 		            geoJSONResult.features.sort(function (a, b) {return b.properties.views - a.properties.views;}); 		            addMarkerColors(geoJSONResult); 					map.addGeoJSONLayer(geoJSONResult, {name: "wikidata items"}); 					if ($("#wd-table")[0].checked) { 		            	dumpListings(geoJSONResult); 					} 		        }); 			} else { 				map.addGeoJSONLayer(geoJSONResult, {name: "wikidata items"}); 				if ($("#wd-table")[0].checked) { 					dumpListings(geoJSONResult); 				} 			} 		}  		function getOSMGeoJSON(lat, lon) { 			function makeOSMQuery( endpointUrl, query ) { 				var settings = { 					headers: { Accept: 'application/json' }, 					data: { data: query } // encodeURIComponent(query) 				}; 				return $.ajax( endpointUrl, settings ); 			} 			 			var auxFilter = ""; 			var bbox, jsonreq; 			var nodeFilterBase, wayFilterBase; 			if ($("#query-radius")[0].checked) { 				var radius = $("#query-radius-km")[0].value; 				nodeFilterBase = "node(around:" + String(radius * 1000) + ", " + String(lat) + ", " + String(lon) + ")"; 				wayFilterBase = "way(around:" + String(radius * 1000) + ", " + String(lat) + ", " + String(lon) + ")"; 				bbox = ""; 				jsonreq = '[out:json];' 			} else { 				bbox = "[bbox:" + $("#query-sw")[0].value + "," + $("#query-ne")[0].value + "];"; 				jsonreq = '[out:json]' 				nodeFilterBase = "node"; 				wayFilterBase = "way"; 			} 			if ($("#osm-filter")[0].value != "") { 				var f = $("#osm-filter")[0].value; 				auxFilter += nodeFilterBase + f + ";"; 				auxFilter += wayFilterBase + f + ";"; 			}  			if ($("#osm-filter-historic")[0].checked) { 				auxFilter += nodeFilterBase + '["historic"~"."]["name"~"."];'; 				auxFilter += wayFilterBase + '["historic"~"."]["name"~"."];'; 			} 			if ($("#osm-filter-viewpoint")[0].checked) { 				auxFilter += nodeFilterBase + '["tourism"~"viewpoint"];'; 				auxFilter += wayFilterBase + '["tourism"~"viewpoint"];'; 			} 			if ($("#osm-filter-museum")[0].checked) { 				auxFilter += nodeFilterBase + '["tourism"~"museum"];'; 				auxFilter += wayFilterBase + '["tourism"~"museum"];'; 			}  			var endpointUrl = 'https://overpass-api.de/api/interpreter', 				overpassQuery = jsonreq + bbox + "( " + auxFilter + "); out tags center;";  			return makeOSMQuery( endpointUrl, overpassQuery).then(function(data){osmResponse = data;}); 		}  		// Getting GeoJSON data sets from external sources (OSM, Commons) 		function getGeoJSON( obj ) { 			var promise, coordinates, feature, geometry, i, j, 				world = [ [ [ 3600, -180 ], [ 3600, 180 ], [ -3600, 180 ], [ -3600, -180 ], [ 3600, -180 ] ] ], 				properties = obj.properties; // for all but not for 'page'  			promise = $.ajax( { // instead of $.getJSON 				dataType: 'json',     			url: obj.url,     			timeout: 3000 			} ).then( function( geoJSON ) { 				switch ( obj.service ) { 					case 'page': 						if ( geoJSON.jsondata && geoJSON.jsondata.data ) { 							$.extend( obj, geoJSON.jsondata.data ); 						} 						break;  					case 'geomask': 						coordinates = world; 						for ( i = 0; i < geoJSON.features.length; i++ ) { 							geometry = geoJSON.features[ i ].geometry; 							if ( !geometry ) { 								continue; 							}  							// push only first polygon 							switch ( geometry.type ) { 								case 'Polygon': 									coordinates.push( geometry.coordinates[ 0 ] ); 									break; 								case 'MultiPolygon': 									for ( j = 0; j < geometry.coordinates.length; j++ ) { 										coordinates.push( geometry.coordinates[ j ][ 0 ] ); 									} 							} 						} 						obj.type = 'Feature'; 						obj.geometry = { type: 'Polygon', coordinates: coordinates }; 						if ( !properties ) { 							properties = defaultProperties; 						} 						if ( $.isEmptyObject( obj.properties ) ) { 							obj.properties = properties; 						} else { 							obj.properties = $.extend( {}, properties, obj.properties ); 						} 						break;  					case 'geoline': 					case 'geoshape': 						$.extend( obj, geoJSON );  						if ( properties ) { 							for ( i = 0; i < obj.features.length; i++ ) { 								feature = obj.features[ i ]; 								if ( $.isEmptyObject( feature.properties ) ) { 									feature.properties = properties; 								} else { 									feature.properties = 										$.extend( {}, properties, feature.properties ); 								} 							} 						} 				} 			}, function() { 				// failed. Do nothing. 			} );  			return promise; 		}  		// Creating attribution strings 		function getAttribution( obj ) { 			var uri = new mw.Uri( obj.url ), link = '';  			switch ( obj.service ) { 				case 'page': 					link = mw.msg( 'project-localized-name-commonswiki' ) + ': ' + 						'<a target="_blank" href="' + 						'//commons.wikimedia.org/wiki/Data:' + encodeURI( uri.query.title ) + 						'">' + uri.query.title + '</a>'; 					break;  				default: // other services 			} 			 			return link; 		}  		// getting Kartographer live data 		function getKartographerLiveData() { 			var group, i, obj, 				promiseArray = [], 				attributions, link;  			data = mw.config.get( 'wgKartographerLiveData' ); 			if ( data ) { 				groups = []; // start with empty global array 				for ( group in data ) { 					// ignoring empty groups 					if ( data[ group ].length ) { 						attributions = []; 						for ( i = 0; i < data[ group ].length; i++ ) { 							obj = data[ group ][ i ]; 							// expand external data 							if ( obj.type === 'ExternalData' && obj.url ) { 								promiseArray.push( getGeoJSON( obj ) ); 								link = getAttribution( obj ); 								if ( link !== '' ) { 									attributions.push( link ); 								} 							} 						} 						attributions = attributions.join( ', ' ); 						groups.push( { name: group, attribution: attributions } ); 					} 				} 			} 			 			// wait for getting all external data 			// regardless of failures, addMapTools() will be executed 			if ( typeof Promise !== 'undefined' ) { 				Promise.all( promiseArray ) 					.then( function() { 						addMapTools(); 					} ) 					// initialization also in case of failures 					// maybe external data are not shown 					.catch( function() { 						addMapTools(); 					} ); 			} else { 				addMapTools(); // for really old browsers 			} 		}  		// getting all vCard/listing and marker information from article 		function getPOIsFromArticle() { 			// initally try to get wgKartographerLiveData because of masks 			// no marker(s): mw.config.get( 'wgKartographerLiveData' ) returns null 			// no map(s): all group arrays like see, do, etc. are empty 			// see phabricator task T183770  			// no wgKartographerLiveData or empty arrays 			data = {}; 			var markers = $( markerSelector ); 			if ( !markers.length ) { 				return; 			}  			var clone, color, desc, group, image, lat, link, lon, symbol, 				$this, title, wikiLink;  			markers.each( function() { 				$this = $( this ); 				link = $( kartographerSelector, $this ).first(); 				if ( link.length ) { 					lat = link.attr( dataLat ); 					lon = link.attr( dataLon ); 					color = $this.attr( dataColor ); 					group = $this.attr( dataGroup );  					// check if only marker number and no HTML tag 					symbol = $this.attr( dataSymbol ); 					if (symbol && symbol.charAt( 0 ) === '-' ) { 						symbol = link.text(); 					}  					// getting title 					title = $( '.' + nameClass, $this ).first(); 					clone = title.clone(); 					$( '.image', clone ).remove(); // remove images from title 					wikiLink = $( 'a', clone ).first(); 					clone.remove(); 					title = ( wikiLink.length ) ? wikiLink[ 0 ].outerHTML : 						$this.attr( dataName );  					// putting image to description 					desc = ''; 					image = $( '.' + imageClass, $this ); 					if ( image.length ) { 						desc = image.html() 							// for mobile view: show image from noscript instead of placeholder 							.replace( '<noscript>', '' ).replace( '</noscript>', '' ); 					}  					// adding to GeoJSON data table 					singleDataset( color, symbol, title, lat, lon, desc, group ); 				} 			} );  			groups = []; // start with empty array 			for ( group in data ) { 				groups.push( { name: group, attribution: '' } ); 			} 		}  		// returning zoom parameter string as a valid number 		function getZoom( s, defaultValue ) { 			var zoom = ( typeof s == 'string' ) ? parseInt( s ) : -1; 			if ( zoom < 0 || zoom > maxZoomLevel ) { 				return defaultValue || defaultMapZoomLevel; 			} 			return zoom; 		}  		function makeContainer( id, style="height: 500px" ) { 			return $( '<div></div>', { id: id, role: 'dialog', 'data-ver': ver, style: style } ); 		}  		// displaying a map by clicking the geo-indicator button 		function indicatorMap() { 			var indicator = $( indicatorSelector ).first(); 			if ( !indicator.length ) { 				return; 			} 			$( indicatorCoordsSelector ).attr( 'target', '_blank' );  			var id = indicatorMapContainerId; 			var options = { 				withClose: true, 				withControls: true, 				withData: true, 				show: defaultShowArray, 				withDialog: false, 				allowFullScreen: true, 				isFullScreen: false, 				featureType: 'mapframe' 			};  			var lat, lon, zoom, center; 			 			var coords = getArticleCoords(); 			lat = coords[0]; 			lon = coords[1]; 			zoom = coords[2]; 			 			// var zoom = getZoom( indicator.attr( dataZoom ) ), 			// 	lat = indicator.attr( dataLat ), 			// 	lon = indicator.attr( dataLon ), 			center = [ lat, lon ];  			// no POIs --> show blue map-center marker 			if ( !groups.length ) { 				singleDataset( '#3366cc', '', messages.mapCenter, lat, lon, '', 					messages.defaultGroupName ); 				groups = [ { name: messages.defaultGroupName, attribution: '' } ]; 			}  			// add or modify indicator action buttons 			var mapTitle = mw.format( messages.mapOf, pageTitle ); 			if ( isMinerva ) { // mobile view 				// add indicator action button and event handler  				var indicatorImg = $( '<img>', { 					src: indicatorGlobeImgSrc, 					width: '20', height: '20' 				} ); 				indicator = $( '<a>', { 						id: 'mw-indicator-i3-geo', 						title: mw.format( messages.indicatorButtonTitle, pageTitle ), 						class: 'mw-indicator', href: '#' 					} ) 					.css( { display: 'inline-block' } ) 					.append( indicatorImg ) 					.append( document.createTextNode( ' ' + messages.indicatorActionLabel ) ); 				indicator = $( '<li>', { 						id: 'page-actions-i3-geo', 						class: 'page-actions-menu__list-item' 					} ) 					.append( indicator ) 					.click( function() { 						if (mapHandle) { 							var oldcenter = mapHandle.getCenter(); 							center = [oldcenter.lat, oldcenter.lng] 							zoom = mapHandle.getZoom(); 						} 						var container = $( '#' + id ); 						if ( container.length ) { 							container.remove(); 							if ($("#maptool-listings").length != 0) 								$("#maptool-listings")[0].remove(); 						} 						{ 							$( '#bodyContent' ).prepend( makeContainer( id ) ); 							$('#' + id).css("resize", ($("#wd-map-resizable")[0].checked ? "both" : "none")); 							var qcenter = $("#query-radius-center")[0].value.split(','); 							var qlat = parseFloat(qcenter[0]); 							var qlon = parseFloat(qcenter[1]);  							wikidataResponse = null; 							osmResponse = null; 							var promiseArray = []; 							if ($("#wd-enable")[0].checked) 								promiseArray.push(getWDGeoJSON(qlat, qlon)); 							if ($("#osm-enable")[0].checked) 								promiseArray.push(getOSMGeoJSON(qlat, qlon)); 							Promise.all( promiseArray ) 							.then( function() { 								createMap( id, center, zoom, mapTitle, options ); 							} ) 							 						} 					} ); 				$( '#page-actions #page-actions-edit' ).after( indicator ); 			} else { // desktop views 				// replace indicator image and add an event handler  				$( indicatorSelector + ' .voy-map-globe-default' ) 					.css( { display: 'none' } ); 				$( indicatorSelector + ' .voy-map-globe-js' ) 					.css( { display: 'inline', cursor: 'pointer' } ) 					.attr( 'title', mw.format( messages.indicatorButtonTitle, pageTitle ) ) 					.click( function() { 						var style = "height: 500px"; 						if (mapHandle) { 							var oldcenter = mapHandle.getCenter(); 							center = [oldcenter.lat, oldcenter.lng] 							zoom = mapHandle.getZoom(); 							style = "width: " + $("#" + id).width() + "px;" + 									"height: " + $("#" + id).height() + "px;"; 						} 						var container = $( '#' + id ); 						if ( container.length ) { 							container.remove(); 							if ($("#maptool-listings")) 								$("#maptool-listings")[0].remove(); 						} 						{ 							$( '#contentSub' ).after( makeContainer( id, style ) ); 							$('#' + id).css("resize", ($("#wd-map-resizable")[0].checked ? "both" : "none")); 							var qcenter = $("#query-radius-center")[0].value.split(','); 							var qlat = parseFloat(qcenter[0]); 							var qlon = parseFloat(qcenter[1]);  							wikidataResponse = null; 							osmResponse = null; 							var promiseArray = []; 							if ($("#wd-enable")[0].checked) 								promiseArray.push(getWDGeoJSON(qlat, qlon)); 							if ($("#osm-enable")[0].checked) 								promiseArray.push(getOSMGeoJSON(qlat, qlon)); 							Promise.all( promiseArray ) 							.then( function() { 								createMap( id, center, zoom, mapTitle, options ); 							} ); 						} 					} ); 			} 		}  		// returning show parameter string as an array 		function getShow( s ) { 			return ( s ) ? JSON.parse( s ) : defaultShowArray; 		}  		// replace the Maplink links by MapTools to show Wikivoyage controls 		// see also: phabricator T180909 		function replaceMaplinks() { 			var links = $( kartographerSelector ); 			if ( !links.length ) { 				return; 			}  			var id = fullScreenContainerId; 			var options = { 				withClose: true, 				withControls: true, 				withData: true, 				show: null, 				withDialog: true, 				allowFullScreen: false, 				isFullScreen: true, 				featureType: 'maplink' 			};  			var center, color, isInvers, lat, lon, name, symbolText, target, wrapper, zoom, $this;  			links.each( function() { 				$this = $( this );  				$this.attr( 'href', '#' ) 					.css( { cursor: 'pointer', 'pointer-events': 'auto', 						'text-decoration': 'none' } );  				$this.click( function( event ) { 					event.stopImmediatePropagation(); 					event.preventDefault();  					// marker could contain an image -> closest 					target = $( event.target ).closest( kartographerSelector ); 					wrapper = target.closest( markerSelector );  					lat = target.attr( dataLat ); 					lon = target.attr( dataLon ); 					center = [ lat, lon ]; 					zoom = getZoom( target.attr( dataZoom ), defaultMaplinkZoomLevel );  					name = wrapper.attr( dataName ) || ''; 					symbolText = target.text(); 					if ( symbolText !== '' ) { 						color = wrapper.attr( dataColor ); 						isInvers = target.closest( '.listing-map-inverse' ).length; 					} 					if ( name === '' ) { 						name = symbolText; 					} else if ( name !== '' && symbolText !== '' ) { 						name = symbolText + '​: ' + name; 					}  					options.show = getShow( target.attr( dataOverlays ) );  					$body.append( makeContainer( id ) ); 					createMap( id, center, zoom, name, options, color, isInvers );  					return false; // don't follow the link 				} ); 			} ); 		}  		// adding a magnify button to Kartographer container 		function addMagnifyButton() { 			var maps = $( mapframeContainerSelector ); 			if ( !maps.length ) { 				return; 			}  			var id = fullScreenContainerId; 			var options = { 				withClose: true, 				withControls: true, 				withData: true, 				show: null, 				withDialog: true, 				allowFullScreen: false, 				isFullScreen: true, 				featureType: 'maplink' 			};  			var caption, center, height, link, map, name, target, $this, zoom, 				zoomIncr;  			maps.each( function() { 				$this = $( this );  				// no magnify button if zoom is already maxZoomLevel 				// not in frameless mode 				map = $( mapframeMapSelector, $this ).first(); 				caption = $( '.thumbcaption', $this ).first(); 				zoom = getZoom( map.attr( dataZoom ) ); 				if ( map.length && caption.length && zoom < maxZoomLevel ) { 					link = $( '<a class="internal"></a>' ) 						.css( { cursor: 'pointer' } ) 						.attr( 'title', messages.magnifyButtonTitle ) 						.click( function( event ) { 							target = $( event.target ); 							map = target.closest( mapframeContainerSelector ); 							caption = $( '.thumbcaption', map ).first(); 							name = caption.text();  							// getting initial position from data if lat or lon 							// or zoom are undefined 							map = $( mapframeMapSelector, map ).first(); 							center = [ map.attr( dataLat ), map.attr( dataLon ) ]; 							zoom = Number( map.attr( dataZoom ) ); 							if ( isNaN( zoom ) ) { 								zoom = undefined; 							} else { 								zoomIncr = 1; 								height = screen.height / map.attr( dataHeight ); 								if ( height > 4 ) { 									zoomIncr++; 								} 								if ( height > 8 ) { 									zoomIncr++; 								} 								zoom += zoomIncr; 								if ( zoom > maxZoomLevel ) { 									zoom = maxZoomLevel; 								} 							}  							options.show = getShow( map.attr( dataOverlays ) );  							$body.append( makeContainer( id ) ); 							createMap( id, center, zoom, name, options ); 						} ); 					caption.prepend( $( '<div class="magnify"></div>' ).append( link ) ); 				} 			} ); 		}  		// showing all articles on an earth map 		function articlesMap() { 			var map = $( '#' + articlesMapId ).first(); 			if ( !map.length ) { 				return; 			}  			var options = { 				withClose: false, 				withControls: true, 				withData: false, 				withDialog: false, 				isFullScreen: false, 				allowFullScreen: false, 					// because Nearby mode cannot be toggled in full-screen mode 				enableNearby: true, 				toggleNearby: true, 				featureType: 'mapframe' 			};  			var zoom = Math.floor( map.height() / 500 ); 			if ( zoom < 0 ) { 				zoom = 0; 			} else if ( zoom > maxZoomLevel ) { 				zoom = maxZoomLevel; 			} 			createMap( articlesMapId, [ 0, 0 ], zoom, messages.articlesMapTitle, options ); 		}  		// adding all tools 		// called by getKartographerLiveData() 		function addMapTools() { 			// groups array is set by getKartographerLiveData() 			// if groups array is empty try to get data from article 			if ( !groups.length ) { 				getPOIsFromArticle(); 			}  			addMagnifyButton(); 			indicatorMap(); 			replaceMaplinks(); 			if ( useArticlesMap ) { 				articlesMap(); 			} 		}  		function init() { 			setupMessages(); 			defaultShowArray = JSON.parse( messages.defaultShow ), 			getKartographerLiveData(); // calling addMapTools() 		}  		return { init: init }; 	} ();  	$( mapTools.init );  } ( jQuery, mediaWiki ) );  //</nowiki>