MediaWiki:Wikiminiatlas.js: Difference between revisions

From SPCodex, The Smashing Pumpkins wiki
(Fix fatal error, this variable is not defined on every page that Wikiminiatlas is loaded on (causes an error sometimes on test2 wiki with IE8))
m (242 revisions imported)
 
(39 intermediate revisions by 5 users not shown)
Line 1: Line 1:
// '''WikiMiniAtlas'''  
// '''WikiMiniAtlas'''
// Script to embed interactive maps into pages that have coordinate templates
// Script to embed interactive maps into pages that have coordinate templates
// also check my user page [[User:Dschwen]] for more tools
// also check my user page [[User:Dschwen]] for more tools
//
//
// Revision 16.9
// Revision 16.11
// Source: https://github.com/dschwen/wikiminiatlas/blob/master/wikiminiatlas.js
/* jshint laxcomma:true, smarttabs:true, quotmark:single, curly:false, es3:true, browser:true */
/* global mw,jQuery */
jQuery(function ($) {
jQuery(function ($) {
  var config = {
// WMA config
  var wc = {
   width  : 600,
   width  : 600,
   height : 400,
   height : 400,
Line 12: Line 16:
   enabled : true,
   enabled : true,
   onlytitle : false,
   onlytitle : false,
   flowTextTooltips: (location.host === "en.wikipedia.org"),
   flowTextTooltips: (location.host==='en.wikipedia.org'),
   alwaysTooltips: false,
   alwaysTooltips: false,
   iframeurl : '//toolserver.org/~dschwen/wma/iframe.html',
   iframeurl : '//wma.wmflabs.org/iframe.html',
   imgbase  : '//toolserver.org/~dschwen/wma/tiles/',
   imgbase  : '//wma.wmflabs.org/tiles/',
   buttonImage: '//upload.wikimedia.org/wikipedia/commons/thumb/5/55/WMA_button2b.png/17px-WMA_button2b.png'
   buttonImage: '//upload.wikimedia.org/wikipedia/commons/thumb/5/55/WMA_button2b.png/17px-WMA_button2b.png',
  buttonImage2x: '//upload.wikimedia.org/wikipedia/commons/thumb/5/55/WMA_button2b.png/34px-WMA_button2b.png'
  },
  },
  strings = {
  strings = {
Line 23: Line 28:
   als:'Ort uf dr interaktivä Chartä zeigä',
   als:'Ort uf dr interaktivä Chartä zeigä',
   ar:'شاهد الموقع على الخريطة التفاعلية',
   ar:'شاهد الموقع على الخريطة التفاعلية',
  ast:'Ver el llugar nun mapa interactivu',
  az: 'Yeri interaktiv bir xəritədə göstər',
  bar:'Ort af da interaktivn Kartn zoagn',
   'be-tarask':'паказаць месцазнаходжаньне на інтэрактыўнай мапе',
   'be-tarask':'паказаць месцазнаходжаньне на інтэрактыўнай мапе',
   'be-x-old':'паказаць месцазнаходжаньне на інтэрактыўнай мапе',
   'be-x-old':'паказаць месцазнаходжаньне на інтэрактыўнай мапе',
   bar:'Ort af da interaktivn Kartn zoagn',
   bg:'Покажи местоположението на интерактивната карта',
   bg:'покажи местоположението на интерактивната карта',
   bh:'इंटरैक्टिव नक्सा पर लोकेशन देखल जाय',
   bpy:'জীবন্ত মানচিত্রগর মা মাপাহান দেখাদিতই',
   bpy:'জীবন্ত মানচিত্রগর মা মাপাহান দেখাদিতই',
   br:'diskouez al lec\'hiadur war ur gartenn etrewezhiat',
   br:'diskouez al lec\'hiadur war ur gartenn etrewezhiat',
   ca:'mostra la localització en un mapa interactiu',
   ca:'Mostra la localització en un mapa interactiu',
   cs:'zobraz místo na interaktivní mapě',
   cs:'zobraz místo na interaktivní mapě',
   da:'vis beliggenhed på interaktivt kort',
   da:'vis beliggenhed på interaktivt kort',
Line 35: Line 43:
   dsb:'Městno na interaktiwnej kórśe zwobrazniś',
   dsb:'Městno na interaktiwnej kórśe zwobrazniś',
   fa:'نمایش مکان در نقشه‌ای پویا',
   fa:'نمایش مکان در نقشه‌ای پویا',
   el:'εμφάνιση τοποθεσίας σε διαδραστικό χάρτη',
   el:'Εμφάνιση τοποθεσίας σε διαδραστικό χάρτη',
   en:'Show location on an interactive map',
   en:'Show location on an interactive map',
   bn:'সক্রিয় মানচিত্রে অবস্থান চিহ্নিত করুন',
   bn:'সক্রিয় মানচিত্রে অবস্থান চিহ্নিত করুন',
Line 46: Line 54:
   gl:'Amosar o lugar nun mapa interactivo',
   gl:'Amosar o lugar nun mapa interactivo',
   he:'הראה מיקום במפה האינטראקטיבית',
   he:'הראה מיקום במפה האינטראקטיבית',
   hi:'सक्रिय नक्शे पर लोकेशन या स्थान दिखायें',  
   hi:'सक्रिय नक्शे पर लोकेशन या स्थान दिखायें',
   hr:'prikaži lokaciju na interaktivnom zemljovidu',
   hr:'prikaži lokaciju na interaktivnom zemljovidu',
   hsb:'Městno na interaktiwnej karće zwobraznić',
   hsb:'Městno na interaktiwnej karće zwobraznić',
Line 58: Line 66:
   kk:'интерактивті картадан орналасуын көрсету',
   kk:'интерактивті картадан орналасуын көрсету',
   km:'បង្ហាញទីតាំងនៅលើផែនទីអន្តរកម្ម',
   km:'បង្ហាញទីតាំងនៅលើផែនទីអន្តរកម្ម',
  kn:'ನಕ್ಷೆಯಲ್ಲಿ ಸ್ಥಳವನ್ನು ತೋರಿಸು',
   ko:'인터랙티브 지도에 위치를 표시',
   ko:'인터랙티브 지도에 위치를 표시',
   lt:'Rodyti vietą interaktyviame žemėlapyje',
   lt:'Rodyti vietą interaktyviame žemėlapyje',
Line 63: Line 72:
   min:'Tunjuakan lokasi pado peta',
   min:'Tunjuakan lokasi pado peta',
   mk:'прикажи положба на интерактивна карта',
   mk:'прикажи положба на интерактивна карта',
  ms:'Tunjukkan lokasi pada peta interaktif',
  my:'မြေပုံပေါ်တွင် တည်နေရာပြရန်',
   nl:'de locatie op een interactieve kaart tonen',
   nl:'de locatie op een interactieve kaart tonen',
   no:'vis beliggenhet på interaktivt kart',
   no:'vis beliggenhet på interaktivt kart',
Line 70: Line 81:
   ro:'Arată locaţia pe o hartă interactivă',
   ro:'Arată locaţia pe o hartă interactivă',
   ru:'показать положение на интерактивной карте',
   ru:'показать положение на интерактивной карте',
  sco:'Shaw location on an interactive cairt',
   sk:'zobraz miesto na interaktívnej mape',
   sk:'zobraz miesto na interaktívnej mape',
   sl:'Prikaži lego na interaktivnem zemljevidu',
   sl:'Prikaži lego na interaktivnem zemljevidu',
Line 77: Line 89:
   sv:'visa platsen på en interaktiv karta',
   sv:'visa platsen på en interaktiv karta',
   tr:'Yeri interaktif bir haritada göster',
   tr:'Yeri interaktif bir haritada göster',
   uk:'показати положення на інтерактивній карті',
   uk:'показати положення на інтерактивній мапі',
   vi:'xem vị trí này trên bản đồ tương tác',
   vi:'xem vị trí này trên bản đồ tương tác',
   vo:'Jonön topi su kaed itjäfidik',
   vo:'Jonön topi su kaed itjäfidik',
Line 87: Line 99:
   },
   },
   map: {
   map: {
  ast:'Mapa',
  az:'Xəritə',
  bg:'Карта',
  bh:'नक्सा',
  bn:'মানচিত্র',
  bs:'Karta',
  ca:'Mapa',
  de:'Karte',
  el:'Χάρτης',
   en:'Map',
   en:'Map',
   es:'Mapa',
   es:'Mapa',
  de:'Karte',
   fa:'نقشه',
   fa:'نقشه',
   fi:'Kartalla',
   fi:'Kartalla',
   fr:'Carte',
   fr:'Carte',
   gl:'Mapa',
   gl:'Mapa',
  hu:'Térkép',
   id:'peta',
   id:'peta',
   ilo:'Mapa',
   ilo:'Mapa',
   ja:'地図',
   ja:'地図',
  kn:'ನಕ್ಷೆ',
   min:'peta',
   min:'peta',
   mk:'карта',
   mk:'Карта',
  ms:'Peta',
  my:'မြေပုံညွှန်း',
   nl:'Kaart',
   nl:'Kaart',
   pt: 'Mapa',
   pt:'Mapa',
   ru:'карте'
   ru:'карте',
  sco:'Cairt',
  sv:'Karta',
  uk:'мапі',
  zh:'地圖',
  'zh-cn':'地图',
  'zh-sg':'地图',
  'zh-tw':'地圖',
  'zh-hk':'地圖'
   },
   },
   close : {
   close : {
Line 107: Line 139:
   als:'Zuä machä',
   als:'Zuä machä',
   ar:'غلق',
   ar:'غلق',
  ast:'zarrar',
  az:'bağla',
   'be-tarask':'закрыць',
   'be-tarask':'закрыць',
   'be-x-old':'закрыць',
   'be-x-old':'закрыць',
   bar:'zuamachn',
   bar:'zuamachn',
   bg:'затвори',
   bg:'Затвори',
  bh:'बंद करीं',
   bpy:'জিপা',
   bpy:'জিপা',
   br:'serriñ',
   br:'serriñ',
   ca:'tanca',
  bs:'zatvori',
   ca:'Tanca',
   cs:'zavřít',
   cs:'zavřít',
   da:'luk',
   da:'luk',
Line 122: Line 158:
   en:'close',
   en:'close',
   bn:'বন্ধ করুন',
   bn:'বন্ধ করুন',
   eo:'fermu',  
   eo:'fermu',
   eu:'itxi',
   eu:'itxi',
   es:'cerrar',
   es:'cerrar',
Line 134: Line 170:
   hr:'zatvori',
   hr:'zatvori',
   hsb:'začinić',
   hsb:'začinić',
   hu:'bezárás',  
   hu:'bezárás',
   hy:'փակել',
   hy:'փակել',
   id:'tutup',
   id:'tutup',
Line 143: Line 179:
   kk:'жабу',
   kk:'жабу',
   km:'បិទ',
   km:'បិទ',
  kn:'ಮುಚ್ಚಿರಿ',
   ko:'닫기',
   ko:'닫기',
   lt:'uždaryti',
   lt:'uždaryti',
Line 148: Line 185:
   min:'tutuik',
   min:'tutuik',
   mk:'затвори',
   mk:'затвори',
  ms:'tutup',
  my:'ပိတ်ရန်',
   nl:'sluiten',
   nl:'sluiten',
   no:'lukk',
   no:'lukk',
Line 171: Line 210:
   },
   },
   resize : {
   resize : {
   ar: 'تغيير حجم',
   ar:'تغيير حجم',
   ca: 'redimensionar',
  ast:'redimensionar',
   de: 'Größe ändern',
  az:'ölçüləri dəyiş',
   dk: 'ændre størrelse',
  bg:'Промени големина',
   en: 'resize',
  bh: 'साइज बदलीं',
   es: 'cambiar el tamaño',
  bn:'মাপ পরিবর্তন করুন',
   fa: 'تغییر اندازه',
   ca:'Redimensiona',
   fi: 'muuta kokoa',
   de:'Größe ändern',
   fr: 'redimensionner',
   dk:'ændre størrelse',
   gl: 'cambiar o tamaño',
  el:'αλλαγή μεγέθους',
   ilo: 'baliwan ti kadakkel',
   en:'resize',
   ja: 'サイズを変更する',
   es:'cambiar el tamaño',
   kk: 'өлшемін өзгерту',
   fa:'تغییر اندازه',
   min: 'gadangan',
   fi:'muuta kokoa',
   mk: 'промени големина',
   fr:'redimensionner',
   nl: 'vergroten of verkleinen',
   gl:'cambiar o tamaño',
   no: 'endre størrelse',
  hu:'átméretezés',
   pt: 'alterar tamanho',
   ilo:'baliwan ti kadakkel',
   ro: 'redimensionare',
   ja:'サイズを変更する',
   sr: 'промени величину',
   kk:'өлшемін өзгерту',
   sv: 'ändra storlek',
  kn:'ಗಾತ್ರ ಬದಲಿಸು',
   zh: '调整大小',
   min:'gadangan',
   'zh-cn': '调整大小'
   mk:'промени големина',
  ms:'ubah saiz',
  my:'အရွယ်အစားညှိရန်',
   nl:'vergroten of verkleinen',
   no:'endre størrelse',
   pt:'alterar tamanho',
   ro:'redimensionare',
  uk:'змінити розмір',
  sl:'spremeni velikost',
   sr:'промени величину',
   sv:'ändra storlek',
   zh:'调整大小',
   'zh-cn':'调整大小',
  'zh-sg':'调整大小',
  'zh-tw':'調整大小',
  'zh-hk':'調整大小'
   }
   }
  },
  },
// domain of the WMA
wma_domain = '//wma.wmflabs.org',
language = '', site = '', awt='0', rtl = /(^|\s)rtl(\s|$)/.test(document.body.className),
// Get a specific, localized string
_msg = function(k) {
  return strings[k][language] || strings[k].en;
},
dbName = mw.config.get( 'wgDBname' ),


language = '', site = '', awt="0",
  iframe = { div: null, iframe: null, closebutton: null, resizebutton: null, resizehelper: null, indom: false },
  iframe = { div: null, iframe: null, closebutton: null, resizebutton: null, resizehelper: null, indom: false },
 
  page_title = (mw.config.get('wgNamespaceNumber')==0) ? encodeURIComponent(mw.config.get('wgTitle')) : '',
  page_title = ( mw.config.get('wgNamespaceNumber')===0 ) ? encodeURIComponent(mw.config.get('wgTitle')) : '',


  bodyc,
  bodyc,
Line 208: Line 271:


  kml = null,
  kml = null,
  mes = null;
  mes = null,
 
  initPromises = [];
// check if we are in a right-to-left-script project
  function isRTL() {
  return /(^|\s)rtl(\s|$)/.test(document.body.className);
}


  // get position on page
  // get position on page
Line 223: Line 282:
  function showIFrame(e) {
  function showIFrame(e) {
   var wi = iframe, my = yPos(this),
   var wi = iframe, my = yPos(this),
       newurl = config.iframeurl + '?wma=' + e.data.param + '&lang=' + site + '&page=' + page_title + '&awt=' + awt;
       newurl = wc.iframeurl + '?wma=' + e.data.param + '&lang=' + site + '&page=' + page_title + '&awt=' + awt;


   // insert iframe into DOM on demand (to preserve page caching)
   // insert iframe into DOM on demand (to preserve page caching)
   if( !wi.indom ) {
   if (!wi.indom) {
   $('#content,#mw_content').prepend(wi.div);
   $('#content,#mw_content').prepend(wi.div);
   wi.indom = true;
   wi.indom = true;
   }
   }


   if( wi.iframe.attr('src') !== newurl ) {
   if (wi.iframe.attr('src')!==newurl) {
   wi.iframe.attr( 'src', newurl );
   wi.iframe.attr( 'src', newurl );
   } else if( wi.div.css('display') !== 'none' ) {
   } else if( wi.div.css('display') !== 'none' ) {
Line 242: Line 301:


  function highlight(i) {
  function highlight(i) {
   if( coord_highlight >= 0 ) {
   if (coord_highlight>=0) {
   $(coord_list[coord_highlight].obj).css('background-color','').find('span:visible').css('background-color','');
   $(coord_list[coord_highlight].obj).css('background-color','').find('span:visible').css('background-color','');
   }
   }
   coord_highlight = i;
   coord_highlight = i;
   if( coord_highlight >= 0 ) {
   if (coord_highlight>=0) {
   $(coord_list[coord_highlight].obj).css('background-color','yellow').find('span:visible').css('background-color','yellow');
   $(coord_list[coord_highlight].obj).css('background-color','yellow').find('span:visible').css('background-color','yellow');
   }
   }
Line 258: Line 317:
   d = e.data.split(',');
   d = e.data.split(',');
   mes = e.source;
   mes = e.source;
   switch(d[0]) {  
   switch(d[0]) {
   case 'request' :
   case 'request' :
     // make a JSON encodable copy of coord_list (no HTML objects!)
     // make a JSON encodable copy of coord_list (no HTML objects!)
     // find center and extent
     // find center and extent
     for( i = 0; i < coord_list.length; ++i ) {
     for (i=0; i<coord_list.length; ++i) {
     clist.coords[i] = {
     clist.coords[i] = {
       lat: coord_list[i].lat,
       lat: coord_list[i].lat,
Line 268: Line 327:
       title: coord_list[i].title.replace(/[\+_]/g,' ')
       title: coord_list[i].title.replace(/[\+_]/g,' ')
     };
     };
     if( coord_list[i].lat < minlat ) { minlat = coord_list[i].lat; }
     if (coord_list[i].lat<minlat) { minlat = coord_list[i].lat; }
     if( coord_list[i].lat > maxlat ) { maxlat = coord_list[i].lat; }
     if (coord_list[i].lat>maxlat) { maxlat = coord_list[i].lat; }
     geoext[i] = {
     geoext[i] = {
       x: Math.cos(coord_list[i].lon/180.0*Math.PI),
       x: Math.cos(coord_list[i].lon/180.0*Math.PI),
       y: Math.sin(coord_list[i].lon/180.0*Math.PI)
       y: Math.sin(coord_list[i].lon/180.0*Math.PI)
     }
     };
     sx += geoext[i].x;
     sx += geoext[i].x;
     sy += geoext[i].y;
     sy += geoext[i].y;
Line 281: Line 340:
     clist.latmin = minlat;
     clist.latmin = minlat;
     // extent in longitude
     // extent in longitude
     for( i = 0; i < geoext.length; ++i ) {
     for (i=0; i<geoext.length; ++i) {
     s = (geoext[i].x*sy-geoext[i].y*sx);
     s = (geoext[i].x*sy-geoext[i].y*sx);
     geoext[i].z = (geoext[i].x*sx+geoext[i].y*sy);
     geoext[i].z = (geoext[i].x*sx+geoext[i].y*sy);
     if( s<0 && ( ineg<0 || geoext[i].z<geoext[ineg].z ) ) { ineg=i; }
     if (s<0 && (ineg<0 || geoext[i].z<geoext[ineg].z)) { ineg=i; }
     if( s>0 && ( ipos<0 || geoext[i].z<geoext[ipos].z ) ) { ipos=i; }
     if (s>0 && (ipos<0 || geoext[i].z<geoext[ipos].z)) { ipos=i; }
     }
     }
     if( ipos>=0 && ineg>=0 ) {
     if (ipos>=0 && ineg>=0) {
     clist.lonleft  = coord_list[ipos].lon;
     clist.lonleft  = coord_list[ipos].lon;
     clist.lonright = coord_list[ineg].lon;
     clist.lonright = coord_list[ineg].lon;
     }
     }
     if( typeof JSON !== "undefined" ) {
     if ('JSON' in window) {
     mes.postMessage( JSON.stringify(clist), document.location.protocol + '//toolserver.org' );
     mes.postMessage(JSON.stringify(clist), document.location.protocol + wma_domain);
     if( kml !== null ) {
     if (kml!==null) {
       mes.postMessage( JSON.stringify(kml), document.location.protocol + '//toolserver.org' );
       mes.postMessage(JSON.stringify(kml), document.location.protocol + wma_domain);
     }
     }
     }
     }
    break;
   case 'unhighlight' :
   case 'unhighlight' :
     highlight(-1);  
     highlight(-1);
     break;
     break;
   case 'toggle' :  
   case 'toggle' :
     coord_list[parseInt(d[1])].mb.click();
     coord_list[parseInt(d[1],10)].mb.click();
     break;
     break;
   case 'scroll' :
   case 'scroll' :
     $("html:not(:animated),body:not(:animated)").animate({ scrollTop: $(coord_list[parseInt(d[1])].obj).offset().top - 20 + parseInt(d[2]||0) }, 500 );
     $('html:not(:animated),body:not(:animated)').animate({ scrollTop: $(coord_list[parseInt(d[1],10)].obj).offset().top - 20 + parseInt(d[2]||'0',10) }, 500 );
     iframe.div.css( { top: yPos( coord_list[parseInt(d[1])].obj ) + 'px'} );
     iframe.div.css( { top: yPos( coord_list[parseInt(d[1],10)].obj ) + 'px'} );
     // make sure scroll target gets highlighted
     // make sure scroll target gets highlighted
     setTimeout( function () { highlight(parseInt(d[1])); }, 200 );
     setTimeout(function () { highlight(parseInt(d[1],10)); }, 200);
     break;
     break;
   case 'highlight' :
   case 'highlight' :
     highlight(parseInt(d[1]));
     highlight(parseInt(d[1],10));
     break;
     break;
   }
   }
  }
  }


Line 318: Line 378:
  function parseParams(url) {
  function parseParams(url) {
   var map = {}, h, i, pair = url.substr(url.indexOf('?')+1).split('&');
   var map = {}, h, i, pair = url.substr(url.indexOf('?')+1).split('&');
   for( i=0; i<pair.length; ++i ) {
   for (i=0; i<pair.length; ++i) {
   h = pair[i].split('=');
   h = pair[i].split('=');
   map[h[0]] = h[1];
   map[h[0]] = h[1];
Line 328: Line 388:


  var wi = iframe,
  var wi = iframe,
    wc = config,
     marker = { lat:0, lon:0 }, coordinates = null,
     marker = { lat:0, lon:0 }, coordinates = null,
     link, links, key, len, coord_title, icons, startTime, content, mapbutton;
     links, key, startTime, mapbutton;


  // apply settings
  // apply settings
  if( typeof(wma_settings) === 'object' ) {
  if (typeof wma_settings==='object') {
   for( key in wma_settings ) {
   for (key in wma_settings) {
   if( typeof(wma_settings[key]) === typeof(wc[key]) ) {
   if (typeof wma_settings[key]===typeof wc[key]) { wc[key] = wma_settings[key]; }
    wc[key] = wma_settings[key];
  }
   }
   }
  }
  }


  if( wc.enabled === false ) { return; }
  if (wc.enabled===false) { return; }


  site = ( mw.config.get( 'wgDBname' ) == "commonswiki" ) ? "commons" : mw.config.get( 'wgPageContentLanguage' );
  site = (dbName==='commonswiki') ? 'commons' : (mw.config.get('wgUserVariant') || mw.config.get('wgPageContentLanguage'));
  language = mw.config.get( 'wgUserLanguage' );
  language = mw.config.get( 'wgUserLanguage' );
// bhwiki reports bho as language. I do not understand that yet, so let's add an exception
if (site === 'bho') site = 'bh';


  // remove icons from title coordinates
  // remove icons from title coordinates
  $('#coordinates,#coordinates-title,#tpl_Coordinaten').find('a.image').detach();
  $('#coordinates,#coordinates-title,#tpl_Coordinaten').find('a.image').detach();
 
  bodyc = $( wc.onlytitle ? '#coordinates,#coordinates-title' : 'html' );
  bodyc = $( wc.onlytitle ? '#coordinates,#coordinates-title' : 'html' );
  startTime = (new Date()).getTime();
  startTime = (new Date()).getTime();


  bodyc.find('a.external.text').each( function( key, link ) {
  bodyc.find('a.external.text').each( function( key, link ) {
   var ws, coord_params, params, zoomlevel, globe="Earth";
   var ws, coord_params, params, zoomlevel, globe='Earth';


   // check for timeout (every 10 links only)
   // check for timeout (every 10 links only)
   if( key % 10 === 9 && (new Date()).getTime() > startTime + wc.timeout ) {  
   if (key%10===9 && (new Date()).getTime() > startTime+wc.timeout) {
   return false; // break out of each
   return false; // break out of each
   }
   }


   if( !('href' in link) || !coord_filter.exec(link.href) ){ // invalid links do not contain href attribute in IE!
   if (!('href' in link) || !coord_filter.exec(link.href)) { // invalid links do not contain href attribute in IE!
   return true;
   return true;
   }
   }
   marker.lat=(1.0*RegExp.$1) + ((RegExp.$2||0)/60.0) + ((RegExp.$3||0)/3600.0);
   marker.lat=(1.0*RegExp.$1) + ((RegExp.$2||0)/60.0) + ((RegExp.$3||0)/3600.0);
   if( RegExp.$4 !== 'N' ) { marker.lat*=-1; }
   if (RegExp.$4!=='N') { marker.lat*=-1; }
   marker.lon=(1.0*RegExp.$5) + ((RegExp.$6||0)/60.0) + ((RegExp.$7||0)/3600.0);
   marker.lon=(1.0*RegExp.$5) + ((RegExp.$6||0)/60.0) + ((RegExp.$7||0)/3600.0);
   if( RegExp.$8 === 'W' ) { marker.lon*=-1; }
   if (RegExp.$8==='W') { marker.lon*=-1; }
   coord_params = RegExp.$9;
   coord_params = RegExp.$9;


   // Zoom based on coordinate N/S precision  
   // Zoom based on coordinate N/S precision
   var coord_digits = RegExp.$3 ? 4 : RegExp.$2 ? 2 : RegExp.$1.length - (RegExp.$1+".").indexOf('.') - 1;
   var coord_digits = RegExp.$3 ? 4 : RegExp.$2 ? 2 : RegExp.$1.length - (RegExp.$1+'.').indexOf('.') - 1;
   zoomlevel = coord_digits * Math.log(10)/Math.log(2);
   zoomlevel = coord_digits * Math.log(10)/Math.log(2);


Line 376: Line 436:
   if( /_type:(airport|edu|pass|landmark|railwaystation)/.test(coord_params) ) {
   if( /_type:(airport|edu|pass|landmark|railwaystation)/.test(coord_params) ) {
   zoomlevel = 8;
   zoomlevel = 8;
   } else if( /_type:(event|forest|glacier)/.test(coord_params) ) {
   } else if (/_type:(event|forest|glacier)/.test(coord_params)) {
   zoomlevel = 6;
   zoomlevel = 6;
   } else if( /_type:(adm3rd|city|mountain|isle|river|waterbody)/.test(coord_params) ) {
   } else if (/_type:(adm3rd|city|mountain|isle|river|waterbody)/.test(coord_params)) {
   zoomlevel = 4;
   zoomlevel = 4;
   }
   }


   // wma shows dim approx 4e7m at zoom 0 or 1.5e8 is the scale of zoomlevel 0
   // wma shows dim approx 4e7m at zoom 0 or 1.5e8 is the scale of zoomlevel 0
   if( /_dim:([\d.+-]+)(km|m|_|$)/.exec(coord_params) ) {
   if (/_dim:([\d.+-]+)(km|m|_|$)/.exec(coord_params)) {
   zoomlevel = Math.log( ( RegExp.$2 === "km" ? 4e4 : 4e7 ) / RegExp.$1 ) / Math.log(2);
   zoomlevel = Math.log((RegExp.$2==='km' ? 4e4 : 4e7) / RegExp.$1)/Math.log(2);
   }
   }
   if( /_scale:(\d+)(_|$)/.exec(coord_params) ) {
   if (/_scale:(\d+)(_|$)/.exec(coord_params)) {
   zoomlevel = Math.log( 1.5e8/RegExp.$1 ) / Math.log(2);
   zoomlevel = Math.log(1.5e8/RegExp.$1) / Math.log(2);
   }
   }


   if( wc.zoom !== -1 ) { zoomlevel = wc.zoom; }
   if (wc.zoom!==-1) { zoomlevel = wc.zoom; }
   //if( zoomlevel > 12 ) { zoomlevel = 12; }
   //if( zoomlevel > 12 ) { zoomlevel = 12; }
   if( zoomlevel < 0 ) { zoomlevel = 0; }
   if (zoomlevel<0) { zoomlevel = 0; }


   function capitalize(s) { return s.substr(0,1).toUpperCase()+s.substr(1).toLowerCase(); }
   function capitalize(s) { return s.substr(0,1).toUpperCase()+s.substr(1).toLowerCase(); }
   if( /_globe:([^_&]+)/.test(coord_params) ) { globe = capitalize(RegExp.$1); }
   if (/_globe:([^_&]+)/.test(coord_params)) { globe = capitalize(RegExp.$1); }
   if( $.inArray(globe,["Earth","Moon","Mars","Venus","Mercury","Io","Titan"]) < 0 ) { return; }
   if ($.inArray(globe,['Earth','Moon','Mars','Venus','Mercury','Io','Titan']) < 0 ) { return; }


   // Test the unicode Symbol
   // Test the unicode Symbol
   if( site === 'de' && link.parentNode.id !== 'coordinates' ) {
   if (site==='de' && link.parentNode.id!=='coordinates') {
   mapbutton = $('<span>♁</span>').css('color','blue');
   mapbutton = $('<span>♁</span>').css('color','blue');
   } else {
   } else {
   mapbutton = $('<img>').attr('src', wc.buttonImage);
   mapbutton = $('<img>').attr('src', wc.buttonImage).attr('srcset', wc.buttonImage + ' 1x, ' + wc.buttonImage2x + ' 2x');
   }
   }
   mapbutton.addClass('wmamapbutton').attr( {
   mapbutton.addClass('wmamapbutton noprint').attr( {
   title: strings.buttonTooltip[language] || strings.buttonTooltip.en,
   title: _msg('buttonTooltip'),
   alt: ''  
   alt: ''
   } )
   } )
   .hover(function (){ $(this).css('opacity', 0.75); }, function () { $(this).css('opacity', ''); })
   .on('mouseenter', function (){ $(this).css('opacity', 0.75); })
  .addClass('noprint')
  .on('mouseleave', function () { $(this).css('opacity', ''); })
   .css('padding', isRTL() ? '0px 0px 0px 3px' : '0px 3px 0px 0px' ).css('cursor', 'pointer');
   .css('padding', rtl ? '0px 0px 0px 3px' : '0px 3px 0px 0px' ).css('cursor', 'pointer');


   if( wc.alwaysTooltips || ( wc.flowTextTooltips && $(link).parents('li, table, #coordinates').length == 0 ) ) {
   if (wc.alwaysTooltips || ( wc.flowTextTooltips && $(link).parents('li, table, #coordinates').length===0)) {
   // insert tooltip rather than icon to improve text readability
   // insert tooltip rather than icon to improve text readability
   mapbutton = $('<span>').append(mapbutton).append("&nbsp;WikiMiniAtlas").css('cursor','pointer');
   mapbutton = $('<span>').append(mapbutton).append('&nbsp;WikiMiniAtlas').css('cursor','pointer');
   var tooltip = $('<div>').css( {
   var tooltip = $('<div>').css( {
     backgroundColor: 'white', padding: '0.2em', border: '1px solid black',
     backgroundColor: 'white', padding: '0.2em', border: '1px solid black',
     position: 'absolute', top: '1em', left: '0em',  
     position: 'absolute', top: '1em', left: '0em',
     display: 'none', zIndex : 15
     display: 'none', zIndex : 15
   }).append(mapbutton);
   }).append(mapbutton);
   $(link).wrap(  
   $(link).wrap(
     $('<span/>')
     $('<span>')
     .css( { position: 'relative', whiteSpace: 'nowrap' } )
     .css( { position: 'relative', whiteSpace: 'nowrap' } )
     .mouseleave( function () { tooltip.fadeOut() } )  
     .on('mouseleave', function () { tooltip.fadeOut(); })
     )
     )
     .before( tooltip )
     .before(tooltip)
     .mouseenter( function () { tooltip.fadeIn() } );
     .on('mouseenter', function () { tooltip.fadeIn(); });
   } else {
   } else {
   // insert icon directly
   // insert icon directly
   ws = $(link).css('whiteSpace');
   ws = $(link).css('whiteSpace');
   if( site !== 'de' || link.parentNode.id !== 'coordinates' ) {
   if (site!=='de' || link.parentNode.id!=='coordinates') {
     $(link).wrap( $('<span/>').css('whiteSpace', 'nowrap') ).css('whiteSpace', ws).before(mapbutton);
     $(link).wrap( $('<span>').css('whiteSpace', 'nowrap') ).css('whiteSpace', ws).before(mapbutton);
   } else {
   } else {
     $('#coordinates').append('<span class="noprint coordinates-separator"> | </span>').append(mapbutton);
     $('#coordinates').append('<span class="noprint coordinates-separator"> | </span>').append(mapbutton);
Line 437: Line 497:
   }
   }


   mapbutton.bind( 'click', { param:
   mapbutton.on( 'click', { param:
   marker.lat + '_' + marker.lon + '_' +
   marker.lat + '_' + marker.lon + '_' +
   wc.width + '_' + wc.height + '_' +
   wc.width + '_' + wc.height + '_' +
Line 448: Line 508:
  } ); //end each
  } ); //end each


  var titlebutton = false;
var titlebutton = false;


  function addTitleButton( alat, alon, zoomlevel ) {
function addTitleButton( alat, alon, zoomlevel ) {
    mapbutton = $('<img>')
  mapbutton = $('<img>')
    .hover(function (){ $(this).css('opacity', 0.75); }, function () { $(this).css('opacity', ''); })
  .on('mouseenter', function (){ $(this).css('opacity', 0.75); })
    .css('padding', isRTL() ? '0px 3px 0px 0px' : '0px 0px 0px 3px' ).css('cursor', 'pointer')      
  .on('mouseleave', function () { $(this).css('opacity', ''); })
    .attr('src', wc.buttonImage).addClass('wmamapbutton').addClass('noprint')
  .css('padding', rtl ? '0px 3px 0px 0px' : '0px 0px 0px 3px' ).css('cursor', 'pointer')
    .bind( 'click', { param:
  .attr('src', wc.buttonImage).attr('srcset', wc.buttonImage + ' 1x, ' + wc.buttonImage2x + ' 2x')
      alat + '_' + alon + '_' +
  .addClass('wmamapbutton noprint')
      wc.width + '_' + wc.height + '_' +
  .on( 'click', { param:
      site + '_' + zoomlevel + '_' + language  
    alat + '_' + alon + '_' +
      }, showIFrame ); // zoomlevel!
    wc.width + '_' + wc.height + '_' +
    site + '_' + zoomlevel + '_' + language
  }, showIFrame ); // zoomlevel!


    if(!titlebutton ) {  
  if (!titlebutton) {
    if( $('#coordinates').length ) {
  if ($('#coordinates').length) {
      $('#coordinates').find('img').detach();
    $('#coordinates').find('img').detach();
      $('#coordinates').append(mapbutton);
    $('#coordinates').append(mapbutton);
    } else {
  } else {
      $('<span id="coordinates">'+(strings.map[language] || strings.map.en)+' </span>').append(mapbutton).appendTo('#bodyContent');
    $('<span id="coordinates"></span>').text(_msg('map')).append(mapbutton).appendTo('#bodyContent');
    }
  }
    titlebutton = true;
  titlebutton = true;
    }
   }
   }
}


  // detect and load KML
  // detect and load KML
Line 476: Line 538:
  (function () {
  (function () {
   var i, l = $('div.kmldata')
   var i, l = $('div.kmldata')
     ,alat = 0, alon = 0, np = 0
     ,alat = 0, alon = 0
     ,la1 = Infinity, la2 =- Infinity
     ,la1 = Infinity, la2 =- Infinity
     ,lo1 = Infinity, lo2 =- Infinity
     ,lo1 = Infinity, lo2 =- Infinity
     ,ex,ey;
     ,ex,ey, req;
   for( i = 0; i < l.length; ++i ) {// TODO: replace with .each
 
   for (i=0; i<l.length; ++i) {// TODO: replace with .each
   coordinates = true;
   coordinates = true;
   $.ajax({
   req = $.ajax({
     url: '/wiki/' + encodeURI(l.eq(i).attr('title')) + '?action=raw',
     url: '/wiki/' + encodeURI(l.eq(i).attr('title')) + '?action=raw',
     dataType: 'xml',
     dataType: 'xml',
     success: function (xml) {
     success: function (xml) {
    var zoomlevel;
     function processCoords(t) {
     function processCoords(t) {
       var way = [], c, p = t.split(' '), i, lat, lon;
       var way = [], c, p = t.split(' '), i, lat, lon;
Line 496: Line 561:


         // determine extent of way
         // determine extent of way
         if( lat<la1 ) { la1=lat; }
         if (lat<la1) { la1=lat; }
         if( lon<lo1 ) { lo1=lon; }
         if (lon<lo1) { lo1=lon; }
         if( lat>la2 ) { la2=lat; }
         if (lat>la2) { la2=lat; }
         if( lon>lo2 ) { lo2=lon; }
         if (lon>lo2) { lo2=lon; }
       }
       }
       }
       }
Line 507: Line 572:
     // initialize transfer datastructure
     // initialize transfer datastructure
     kml = { ways: [], areas: [] };
     kml = { ways: [], areas: [] };
window.kmldata = xml; // DEBUG!


     // ways
     // ways
     $(xml).find('LineString > coordinates').each(function () {
     $(xml).find('LineString > coordinates').each(function () {
       var way = processCoords( $(this).text() );
       var way = processCoords( $(this).text() );
       if( way.length > 0 ) { kml.ways.push(way); }
       if (way.length>0) { kml.ways.push(way); }
     });
     });


     // areas
     // areas
     $(xml).find('Polygon').each(function () {
     $(xml).find('Polygon').each(function () {
       var i, j, c,
       var area = { inner: [], outer: [] };
      area = { inner: [], outer: [] };


       // outer boundary
       // outer boundary
       $(this).find('outerBoundaryIs > LinearRing > coordinates').each(function () {
       $(this).find('outerBoundaryIs > LinearRing > coordinates').each(function () {
       var way = processCoords( $(this).text() );
       var way = processCoords($(this).text());
       if( way.length > 0 ) {
       if (way.length>0) { area.outer.push(way); }
        area.outer.push(way);
      }
       });
       });


       // inner boundary (holes in the polygon)
       // inner boundary (holes in the polygon)
       $(this).find('innerBoundaryIs > LinearRing > coordinates').each(function () {
       $(this).find('innerBoundaryIs > LinearRing > coordinates').each(function () {
       var way = processCoords( $(this).text() );
       var way = processCoords($(this).text());
       if( way.length > 0 ) { area.inner.push(way); }
       if (way.length>0) { area.inner.push(way); }
       });
       });


       // only add if we have an outer boundary
       // only add if we have an outer boundary
       if( area.outer.length>0 ) { kml.areas.push(area); }
       if (area.outer.length>0) { kml.areas.push(area); }
     });
     });


Line 543: Line 604:
     kml.minlat = la1;
     kml.minlat = la1;
     kml.maxlat = la2;
     kml.maxlat = la2;
window.kml = kml; // DEBUG!


     // already got a request message
     // already got a request message
     if( mes !== null && kml.ways.length > 0 && typeof JSON !== "undefined" ) {
     if (mes!==null && kml.ways.length>0 && 'JSON' in window) {
       mes.postMessage( JSON.stringify(kml), document.location.protocol + '//toolserver.org' );
       mes.postMessage(JSON.stringify(kml), document.location.protocol + wma_domain);
     }
     }


     // insert blue globe
     // insert blue globe
     if( coord_list.length == 0 || ( !$('#coordinates').find('.wmamapbutton').length) ) {
     if (coord_list.length===0 || (!$('#coordinates').find('.wmamapbutton').length)) {
       // determine center
       // determine center
       alat = (la1+la2)/2;
       alat = (la1+la2)/2;
Line 559: Line 619:
       ex = (lo2-lo1)/180.0 * 3.0*128;
       ex = (lo2-lo1)/180.0 * 3.0*128;
       ey = (la2-la1)/180.0 * 3.0*128; // max extent in degrees, zoom0 has 3*128/180 px/degree
       ey = (la2-la1)/180.0 * 3.0*128; // max extent in degrees, zoom0 has 3*128/180 px/degree
       for( zoomlevel = 0; zoomlevel < 12; ++zoomlevel ) {
       for (zoomlevel=0; zoomlevel<12; ++zoomlevel) {
       if( ex>config.width/2 || ey>config.height/2 ) break;
       if( ex>wc.width/2 || ey>wc.height/2 ) break;
       ex *= 2; ey *= 2;
       ex *= 2; ey *= 2;
       }
       }
Line 569: Line 629:
     }
     }
   });
   });
  // Add request promise to init array, and cast any errors to success so that
  // we don't abort init early when one of the requests failed. These are expected
  // to fail for titles we can't find.
  initPromises.push(req.then(null, function () { return $.Deferred().resolve(); } ));
   } // end for
   } // end for
  })();
  })();


  // detect All Coordinates crap
  // detect "All Coordinates"
  links = $('#coordinates>span>a');
  links = $('#coordinates>span>a');
  if( links.length>0 && links[0].href.substr(0,50) == "http://www.lenz-online.de/cgi-bin/wiki/wiki-osm.pl" ) {
  if (links.length && links[0].href.indexOf('http://www.lenz-online.de/cgi-bin/wiki/wiki-osm.pl') === 0) {
   addTitleButton( 0, 0, 1 );
   addTitleButton( 0, 0, 1 );
   coordinates = true;
   coordinates = true;
Line 580: Line 644:


  // prepare iframe to house the map
  // prepare iframe to house the map
  if ( coordinates !== null ) {
  if (coordinates!==null) {
   wi.div = $('<div/>').css( {
   wi.div = $('<div>').css( {
   width: (wc.width+2)+'px', height: (wc.height+2)+'px',
   width: (wc.width+2)+'px', height: (wc.height+2)+'px',
   margin: '0px', padding: '0px',  
   margin: '0px', padding: '0px',
   backgroundColor : 'white', border: '1px solid gray',
   backgroundColor : 'white', border: '1px solid gray',
   position: 'absolute', top: '1em', zIndex: 13, boxShadow: '3px 3px 25px rgba(0,0,0,0.3)'
   position: 'absolute', top: '1em', zIndex: 13, boxShadow: '3px 3px 25px rgba(0,0,0,0.3)'
   } ).css( isRTL() ? 'left' : 'right', '2em' ).hide();
   } ).css( rtl ? 'left' : 'right', '2em' ).hide();


   var rbrtl = [ '//upload.wikimedia.org/wikipedia/commons/b/b5/Button_resize.png',
   var rbrtl = [ '//upload.wikimedia.org/wikipedia/commons/b/b5/Button_resize.png',
                 '//upload.wikimedia.org/wikipedia/commons/3/30/Button_resize_rtl.png' ]
                 '//upload.wikimedia.org/wikipedia/commons/3/30/Button_resize_rtl.png' ];
   wi.resizebutton = $('<img>').attr( {  
   wi.resizebutton = $('<img>').attr( {
   title : strings.resize[language] || strings.resize.en,
   title : _msg('resize'),
   src : rbrtl[isRTL()?1:0]
   src : rbrtl[rtl?1:0]
   } ).hide().attr('ondragstart','return false');
   } ).hide().attr('ondragstart','return false');
 
 
   // cover the iframe to prevent loosing the mouse to the iframe during resizing
   // cover the iframe to prevent loosing the mouse to the iframe during resizing
   wi.resizehelper = $('<div/>').css( { position: 'absolute', top:0, left:0, zIndex: 20 } ).hide();
   wi.resizehelper = $('<div>').css( { position: 'absolute', top:0, left:0, zIndex: 20 } ).hide();


   wi.closebutton = $('<img>').attr( {  
   wi.closebutton = $('<img>').attr( {
   title : strings.close[language] || strings.close.en,
   title : _msg('close'),
   src : '//upload.wikimedia.org/wikipedia/commons/d/d4/Button_hide.png'
   src : '//upload.wikimedia.org/wikipedia/commons/d/d4/Button_hide.png'
   } ).css( {
   } ).css( {
   zIndex : 15, position : 'absolute', right : '11px', top : '9px', width : '18px', cursor : 'pointer'
   zIndex : 15, position : 'absolute', right : '11px', top : '9px', width : '18px', cursor : 'pointer'
   } ).click( function(e) { wi.div.hide() } );
   } ).click( function(e) { wi.div.hide(); } );


   wi.iframe = $('<iframe/>')
   wi.iframe = $('<iframe>')
   .attr( { scrolling: 'no', frameBorder : 0 } )
   .attr( { scrolling: 'no', frameBorder : 0 } )
   .css( {
   .css( {
Line 617: Line 681:
   wi.div.append(wi.closebutton);
   wi.div.append(wi.closebutton);
   (function () {
   (function () {
   var startx, starty, idle = true, dir = isRTL()?-1:1;
   var idle = true, dir = rtl?-1:1;
   function adjusthelper() {
   function adjusthelper() {
     wi.resizehelper.css( { width: (wc.width+2)+'px', height: (wc.height+2)+'px' } );
     wi.resizehelper.css( { width: (wc.width+2)+'px', height: (wc.height+2)+'px' } );
   }
   }
   wi.div.append(
   wi.div.append(
     $('<div/>')
     $('<div>')
     .css( {
     .css( {
       zIndex : 15, position : 'absolute', bottom : '3px',  
       zIndex : 15, position : 'absolute', bottom : '3px',
       width : '18px', height: '18px', cursor : (isRTL()?'se-resize':'sw-resize'),
       width : '18px', height: '18px', cursor : (rtl?'se-resize':'sw-resize'),
       'user-select': 'none', '-moz-user-select': 'none', '-ms-user-select': 'none'
       'user-select': 'none', '-moz-user-select': 'none', '-ms-user-select': 'none'
       } ).css( (isRTL()?'right':'left'), '3px' )
       } ).css( (rtl?'right':'left'), '3px' )
     .mouseenter( function(e) { wi.resizebutton.fadeIn() } )
     .on('mouseenter', function(e) { wi.resizebutton.fadeIn(); } )
     .mouseleave( function(e) { if( idle ) { wi.resizebutton.fadeOut(); } } )
     .on('mouseleave', function(e) { if( idle ) { wi.resizebutton.fadeOut(); } } )
     .mousedown( function(e) {
     .on('mousedown', function(e) {
       if( idle ) {  
       if (idle) {
        var lastx = e.pageX, lasty = e.pageY;
         wi.resizehelper.show();
         wi.resizehelper.show();
         adjusthelper();
         adjusthelper();
        lastx = e.pageX;
 
        lasty = e.pageY;
         $('body')
         $('body').bind('mouseup.wmaresize', function(e) {  
        .on('mouseup.wmaresize', function(e) {
        $('body').unbind('mousemove.wmaresize');
          $('body').off('mousemove.wmaresize');
        $('body').unbind('mouseup.wmaresize');  
          $('body').off('mouseup.wmaresize');
        idle = true;
          idle = true;
        wi.resizehelper.hide();
          wi.resizehelper.hide();
        } );
        } )
        $('body').bind('mousemove.wmaresize', function(e) {  
        .on('mousemove.wmaresize', function(e) {
        wc.width -= dir*(e.pageX-lastx);
          wc.width -= dir*(e.pageX-lastx);
        wc.height += (e.pageY-lasty);
          wc.height += (e.pageY-lasty);
        lastx = e.pageX; lasty = e.pageY;
          lastx = e.pageX; lasty = e.pageY;
        wi.div.css( { width: (wc.width+2)+'px', height: (wc.height+2)+'px' } );
          wi.div.css( { width: (wc.width+2)+'px', height: (wc.height+2)+'px' } );
        wi.iframe.css( { width: wc.width+'px', height: wc.height+'px' } );
          wi.iframe.css( { width: wc.width+'px', height: wc.height+'px' } );
        adjusthelper();
          adjusthelper();
        } );
        } );
 
         idle = false;
         idle = false;
       }
       }
       } )
       } )
     .append(wi.resizebutton)  
     .append(wi.resizebutton)
   );
   );
   })();
   })();


   $(window).bind('message', messageHub);
   $(window).on('message', messageHub);
 
  // Fire event for other code to extend or integrate with WMA
  if (initPromises.length) {
    $.when.apply( null, initPromises ).then(function () {
      mw.hook('WikiMiniAtlas.load').fire();
    } );
  } else {
    mw.hook('WikiMiniAtlas.load').fire();
  }
  }
  }
});
});


// </nowiki>
// </nowiki>

Latest revision as of 06:28, 1 August 2020

// '''WikiMiniAtlas'''
// Script to embed interactive maps into pages that have coordinate templates
// also check my user page [[User:Dschwen]] for more tools
//
// Revision 16.11
// Source: https://github.com/dschwen/wikiminiatlas/blob/master/wikiminiatlas.js
/* jshint laxcomma:true, smarttabs:true, quotmark:single, curly:false, es3:true, browser:true */
/* global mw,jQuery */
jQuery(function ($) {
 // WMA config
 var wc = {
  width  : 600,
  height : 400,
  timeout : 5000,
  zoom : -1,
  enabled : true,
  onlytitle : false,
  flowTextTooltips: (location.host==='en.wikipedia.org'),
  alwaysTooltips: false,
  iframeurl : '//wma.wmflabs.org/iframe.html',
  imgbase   : '//wma.wmflabs.org/tiles/',
  buttonImage: '//upload.wikimedia.org/wikipedia/commons/thumb/5/55/WMA_button2b.png/17px-WMA_button2b.png',
  buttonImage2x: '//upload.wikimedia.org/wikipedia/commons/thumb/5/55/WMA_button2b.png/34px-WMA_button2b.png'
 },
 strings = {
  buttonTooltip : {
   af:'Vertoon ligging op \'n interaktiwe kaart.',
   als:'Ort uf dr interaktivä Chartä zeigä',
   ar:'شاهد الموقع على الخريطة التفاعلية',
   ast:'Ver el llugar nun mapa interactivu',
   az: 'Yeri interaktiv bir xəritədə göstər',
   bar:'Ort af da interaktivn Kartn zoagn',
   'be-tarask':'паказаць месцазнаходжаньне на інтэрактыўнай мапе',
   'be-x-old':'паказаць месцазнаходжаньне на інтэрактыўнай мапе',
   bg:'Покажи местоположението на интерактивната карта',
   bh:'इंटरैक्टिव नक्सा पर लोकेशन देखल जाय',
   bpy:'জীবন্ত মানচিত্রগর মা মাপাহান দেখাদিতই',
   br:'diskouez al lec\'hiadur war ur gartenn etrewezhiat',
   ca:'Mostra la localització en un mapa interactiu',
   cs:'zobraz místo na interaktivní mapě',
   da:'vis beliggenhed på interaktivt kort',
   de:'Ort auf interaktiver Karte anzeigen',
   dsb:'Městno na interaktiwnej kórśe zwobrazniś',
   fa:'نمایش مکان در نقشه‌ای پویا',
   el:'Εμφάνιση τοποθεσίας σε διαδραστικό χάρτη',
   en:'Show location on an interactive map',
   bn:'সক্রিয় মানচিত্রে অবস্থান চিহ্নিত করুন',
   eo:'Montru lokigon sur interaktiva karto',
   eu:'erakutsi kokalekua mapa interaktibo batean',
   es:'Mostrar el lugar en un mapa interactivo',
   fr:'Montrer la localisation sur une carte interactive',
   fur:'mostre la localizazion suntune mape interative',
   fy:'it plak op in oanpasbere kaart oanjaan',
   gl:'Amosar o lugar nun mapa interactivo',
   he:'הראה מיקום במפה האינטראקטיבית',
   hi:'सक्रिय नक्शे पर लोकेशन या स्थान दिखायें',
   hr:'prikaži lokaciju na interaktivnom zemljovidu',
   hsb:'Městno na interaktiwnej karće zwobraznić',
   hu:'Mutasd a helyet egy interaktív térképen!',
   hy:'ցուցադրել դիրքը ինտերակտիվ քարտեզի վրա',
   id:'Tunjukkan lokasi di peta interaktif',
   ilo:'Ipakita ti lokasion iti interaktibo a mapa',
   is:'sýna staðsetningu á gagnvirku korti',
   it:'mostra la località su una carta interattiva',
   ja:'インタラクティブ地図上に位置を表示',
   kk:'интерактивті картадан орналасуын көрсету',
   km:'បង្ហាញទីតាំងនៅលើផែនទីអន្តរកម្ម',
   kn:'ನಕ್ಷೆಯಲ್ಲಿ ಸ್ಥಳವನ್ನು ತೋರಿಸು',
   ko:'인터랙티브 지도에 위치를 표시',
   lt:'Rodyti vietą interaktyviame žemėlapyje',
   lv:'Rādīt atrašanās vietu interaktīvajā kartē',
   min:'Tunjuakan lokasi pado peta',
   mk:'прикажи положба на интерактивна карта',
   ms:'Tunjukkan lokasi pada peta interaktif',
   my:'မြေပုံပေါ်တွင် တည်နေရာပြရန်',
   nl:'de locatie op een interactieve kaart tonen',
   no:'vis beliggenhet på interaktivt kart',
   nv:'kéyah tʼáá dah siʼą́ą́ ńtʼę́ę́ʼ beʼelyaaígíí',
   pl:'Pokaż lokalizację na mapie interaktywnej',
   pt:'mostrar a localidade num mapa interactivo',
   ro:'Arată locaţia pe o hartă interactivă',
   ru:'показать положение на интерактивной карте',
   sco:'Shaw location on an interactive cairt',
   sk:'zobraz miesto na interaktívnej mape',
   sl:'Prikaži lego na interaktivnem zemljevidu',
   sr:'Прикажи локацију на интерактивној мапи',
   sq:'trego vendndodhjen në hartë',
   fi:'näytä paikka interaktiivisella kartalla',
   sv:'visa platsen på en interaktiv karta',
   tr:'Yeri interaktif bir haritada göster',
   uk:'показати положення на інтерактивній мапі',
   vi:'xem vị trí này trên bản đồ tương tác',
   vo:'Jonön topi su kaed itjäfidik',
   zh:'显示该地在地图上的位置',
   'zh-cn':'显示该地在地图上的位置',
   'zh-sg':'显示该地在地图上的位置',
   'zh-tw':'顯示該地在地圖上的位置',
   'zh-hk':'顯示該地在地圖上的位置'
  },
  map: {
   ast:'Mapa',
   az:'Xəritə',
   bg:'Карта',
   bh:'नक्सा',
   bn:'মানচিত্র',
   bs:'Karta',
   ca:'Mapa',
   de:'Karte',
   el:'Χάρτης',
   en:'Map',
   es:'Mapa',
   fa:'نقشه',
   fi:'Kartalla',
   fr:'Carte',
   gl:'Mapa',
   hu:'Térkép',
   id:'peta',
   ilo:'Mapa',
   ja:'地図',
   kn:'ನಕ್ಷೆ',
   min:'peta',
   mk:'Карта',
   ms:'Peta',
   my:'မြေပုံညွှန်း',
   nl:'Kaart',
   pt:'Mapa',
   ru:'карте',
   sco:'Cairt',
   sv:'Karta',
   uk:'мапі',
   zh:'地圖',
   'zh-cn':'地图',
   'zh-sg':'地图',
   'zh-tw':'地圖',
   'zh-hk':'地圖'
  },
  close : {
   af:'Sluit',
   als:'Zuä machä',
   ar:'غلق',
   ast:'zarrar',
   az:'bağla',
   'be-tarask':'закрыць',
   'be-x-old':'закрыць',
   bar:'zuamachn',
   bg:'Затвори',
   bh:'बंद करीं',
   bpy:'জিপা',
   br:'serriñ',
   bs:'zatvori',
   ca:'Tanca',
   cs:'zavřít',
   da:'luk',
   de:'schließen',
   dsb:'zacyniś',
   nv:'doo yishʼį́ nisin da',
   el:'έξοδος',
   en:'close',
   bn:'বন্ধ করুন',
   eo:'fermu',
   eu:'itxi',
   es:'cerrar',
   fa:'بستن',
   fr:'Quitter',
   fur:'siere',
   fy:'ticht',
   gl:'pechar',
   he:'לסגור',
   hi:'बंद करें',
   hr:'zatvori',
   hsb:'začinić',
   hu:'bezárás',
   hy:'փակել',
   id:'tutup',
   ilo:'irikep',
   is:'loka',
   it:'chiudi',
   ja:'閉じる',
   kk:'жабу',
   km:'បិទ',
   kn:'ಮುಚ್ಚಿರಿ',
   ko:'닫기',
   lt:'uždaryti',
   lv:'aizvērt',
   min:'tutuik',
   mk:'затвори',
   ms:'tutup',
   my:'ပိတ်ရန်',
   nl:'sluiten',
   no:'lukk',
   pl:'zamknij',
   pt:'fechar',
   ro:'închide',
   ru:'закрыть',
   sk:'zatvoriť',
   sl:'zapri',
   sr:'затвори',
   sq:'mbylle',
   fi:'sulje',
   sv:'stäng',
   tr:'kapat',
   uk:'закрити',
   vi:'đóng',
   vo:'färmükön',
   zh:'关闭',
   'zh-cn':'关闭',
   'zh-sg':'关闭',
   'zh-tw':'關閉',
   'zh-hk':'關閉'
  },
  resize : {
   ar:'تغيير حجم',
   ast:'redimensionar',
   az:'ölçüləri dəyiş',
   bg:'Промени големина',
   bh: 'साइज बदलीं',
   bn:'মাপ পরিবর্তন করুন',
   ca:'Redimensiona',
   de:'Größe ändern',
   dk:'ændre størrelse',
   el:'αλλαγή μεγέθους',
   en:'resize',
   es:'cambiar el tamaño',
   fa:'تغییر اندازه',
   fi:'muuta kokoa',
   fr:'redimensionner',
   gl:'cambiar o tamaño',
   hu:'átméretezés',
   ilo:'baliwan ti kadakkel',
   ja:'サイズを変更する',
   kk:'өлшемін өзгерту',
   kn:'ಗಾತ್ರ ಬದಲಿಸು',
   min:'gadangan',
   mk:'промени големина',
   ms:'ubah saiz',
   my:'အရွယ်အစားညှိရန်',
   nl:'vergroten of verkleinen',
   no:'endre størrelse',
   pt:'alterar tamanho',
   ro:'redimensionare',
   uk:'змінити розмір',
   sl:'spremeni velikost',
   sr:'промени величину',
   sv:'ändra storlek',
   zh:'调整大小',
   'zh-cn':'调整大小',
   'zh-sg':'调整大小',
   'zh-tw':'調整大小',
   'zh-hk':'調整大小'
  }
 },
 // domain of the WMA
 wma_domain = '//wma.wmflabs.org',

 language = '', site = '', awt='0', rtl = /(^|\s)rtl(\s|$)/.test(document.body.className),

 // Get a specific, localized string
 _msg = function(k) {
  return strings[k][language] || strings[k].en;
 },
 dbName = mw.config.get( 'wgDBname' ),

 iframe = { div: null, iframe: null, closebutton: null, resizebutton: null, resizehelper: null, indom: false },

 page_title = ( mw.config.get('wgNamespaceNumber')===0 ) ? encodeURIComponent(mw.config.get('wgTitle')) : '',

 bodyc,
 coord_filter = /&params=([\d.+-]+)_([\d.+-]*)_?([\d.+-]*)_?([NSZ])_([\d.+-]+)_([\d.+-]*)_?([\d.+-]*)_?([EOW])([^&=<>|]{0,250})/,
 coord_list = [],
 coord_highlight = -1,

 kml = null,
 mes = null,
 initPromises = [];

 // get position on page
 function yPos(el) {
  return $(el).offset().top + $(el).outerHeight();
 }

 // show, move, and update iframe
 function showIFrame(e) {
  var wi = iframe, my = yPos(this),
      newurl = wc.iframeurl + '?wma=' + e.data.param + '&lang=' + site + '&page=' + page_title + '&awt=' + awt;

  // insert iframe into DOM on demand (to preserve page caching)
  if (!wi.indom) {
   $('#content,#mw_content').prepend(wi.div);
   wi.indom = true;
  }

  if (wi.iframe.attr('src')!==newurl) {
   wi.iframe.attr( 'src', newurl );
  } else if( wi.div.css('display') !== 'none' ) {
   wi.div.hide();
   return false;
  }
  wi.div.css( 'top', my+'px' ).show();
  return false;
 }

 function highlight(i) {
  if (coord_highlight>=0) {
   $(coord_list[coord_highlight].obj).css('background-color','').find('span:visible').css('background-color','');
  }
  coord_highlight = i;
  if (coord_highlight>=0) {
   $(coord_list[coord_highlight].obj).css('background-color','yellow').find('span:visible').css('background-color','yellow');
  }
 }

 function messageHub(e) {
  var i, d, clist = { coords: [] }
    , geoext = [], sx=0, sy=0, s
    , minlat = Infinity, maxlat = -Infinity, ineg = -1, ipos = -1;
  e = e.originalEvent;
  d = e.data.split(',');
  mes = e.source;
  switch(d[0]) {
   case 'request' :
    // make a JSON encodable copy of coord_list (no HTML objects!)
    // find center and extent
    for (i=0; i<coord_list.length; ++i) {
     clist.coords[i] = {
      lat: coord_list[i].lat,
      lon: coord_list[i].lon,
      title: coord_list[i].title.replace(/[\+_]/g,' ')
     };
     if (coord_list[i].lat<minlat) { minlat = coord_list[i].lat; }
     if (coord_list[i].lat>maxlat) { maxlat = coord_list[i].lat; }
     geoext[i] = {
      x: Math.cos(coord_list[i].lon/180.0*Math.PI),
      y: Math.sin(coord_list[i].lon/180.0*Math.PI)
     };
     sx += geoext[i].x;
     sy += geoext[i].y;
    }
    clist.loncenter = Math.atan2(sy,sx)*180.0/Math.PI;
    clist.latmax = maxlat;
    clist.latmin = minlat;
    // extent in longitude
    for (i=0; i<geoext.length; ++i) {
     s = (geoext[i].x*sy-geoext[i].y*sx);
     geoext[i].z = (geoext[i].x*sx+geoext[i].y*sy);
     if (s<0 && (ineg<0 || geoext[i].z<geoext[ineg].z)) { ineg=i; }
     if (s>0 && (ipos<0 || geoext[i].z<geoext[ipos].z)) { ipos=i; }
    }
    if (ipos>=0 && ineg>=0) {
     clist.lonleft  = coord_list[ipos].lon;
     clist.lonright = coord_list[ineg].lon;
    }
    if ('JSON' in window) {
     mes.postMessage(JSON.stringify(clist), document.location.protocol + wma_domain);
     if (kml!==null) {
      mes.postMessage(JSON.stringify(kml), document.location.protocol + wma_domain);
     }
    }
    break;
   case 'unhighlight' :
    highlight(-1);
    break;
   case 'toggle' :
    coord_list[parseInt(d[1],10)].mb.click();
    break;
   case 'scroll' :
    $('html:not(:animated),body:not(:animated)').animate({ scrollTop: $(coord_list[parseInt(d[1],10)].obj).offset().top - 20 + parseInt(d[2]||'0',10) }, 500 );
    iframe.div.css( { top: yPos( coord_list[parseInt(d[1],10)].obj ) + 'px'} );
    // make sure scroll target gets highlighted
    setTimeout(function () { highlight(parseInt(d[1],10)); }, 200);
    break;
   case 'highlight' :
    highlight(parseInt(d[1],10));
    break;
  }
 }

 // parse url parameters into a hash
 function parseParams(url) {
  var map = {}, h, i, pair = url.substr(url.indexOf('?')+1).split('&');
  for (i=0; i<pair.length; ++i) {
   h = pair[i].split('=');
   map[h[0]] = h[1];
  }
  return map;
 }

 // Insert the IFrame into the page.

 var wi = iframe,
     marker = { lat:0, lon:0 }, coordinates = null,
     links, key, startTime, mapbutton;

 // apply settings
 if (typeof wma_settings==='object') {
  for (key in wma_settings) {
   if (typeof wma_settings[key]===typeof wc[key]) { wc[key] = wma_settings[key]; }
  }
 }

 if (wc.enabled===false) { return; }

 site = (dbName==='commonswiki') ? 'commons' : (mw.config.get('wgUserVariant') || mw.config.get('wgPageContentLanguage'));
 language = mw.config.get( 'wgUserLanguage' );

 // bhwiki reports bho as language. I do not understand that yet, so let's add an exception
 if (site === 'bho') site = 'bh';

 // remove icons from title coordinates
 $('#coordinates,#coordinates-title,#tpl_Coordinaten').find('a.image').detach();

 bodyc = $( wc.onlytitle ? '#coordinates,#coordinates-title' : 'html' );
 startTime = (new Date()).getTime();

 bodyc.find('a.external.text').each( function( key, link ) {
  var ws, coord_params, params, zoomlevel, globe='Earth';

  // check for timeout (every 10 links only)
  if (key%10===9 && (new Date()).getTime() > startTime+wc.timeout) {
   return false; // break out of each
  }

  if (!('href' in link) || !coord_filter.exec(link.href)) { // invalid links do not contain href attribute in IE!
   return true;
  }
  marker.lat=(1.0*RegExp.$1) + ((RegExp.$2||0)/60.0) + ((RegExp.$3||0)/3600.0);
  if (RegExp.$4!=='N') { marker.lat*=-1; }
  marker.lon=(1.0*RegExp.$5) + ((RegExp.$6||0)/60.0) + ((RegExp.$7||0)/3600.0);
  if (RegExp.$8==='W') { marker.lon*=-1; }
  coord_params = RegExp.$9;

  // Zoom based on coordinate N/S precision
  var coord_digits = RegExp.$3 ? 4 : RegExp.$2 ? 2 : RegExp.$1.length - (RegExp.$1+'.').indexOf('.') - 1;
  zoomlevel = coord_digits * Math.log(10)/Math.log(2);

  // Find a sensible Zoom-level based on type
  if( /_type:(airport|edu|pass|landmark|railwaystation)/.test(coord_params) ) {
   zoomlevel = 8;
  } else if (/_type:(event|forest|glacier)/.test(coord_params)) {
   zoomlevel = 6;
  } else if (/_type:(adm3rd|city|mountain|isle|river|waterbody)/.test(coord_params)) {
   zoomlevel = 4;
  }

  // wma shows dim approx 4e7m at zoom 0 or 1.5e8 is the scale of zoomlevel 0
  if (/_dim:([\d.+-]+)(km|m|_|$)/.exec(coord_params)) {
   zoomlevel = Math.log((RegExp.$2==='km' ? 4e4 : 4e7) / RegExp.$1)/Math.log(2);
  }
  if (/_scale:(\d+)(_|$)/.exec(coord_params)) {
   zoomlevel = Math.log(1.5e8/RegExp.$1) / Math.log(2);
  }

  if (wc.zoom!==-1) { zoomlevel = wc.zoom; }
  //if( zoomlevel > 12 ) { zoomlevel = 12; }
  if (zoomlevel<0) { zoomlevel = 0; }

  function capitalize(s) { return s.substr(0,1).toUpperCase()+s.substr(1).toLowerCase(); }
  if (/_globe:([^_&]+)/.test(coord_params)) { globe = capitalize(RegExp.$1); }
  if ($.inArray(globe,['Earth','Moon','Mars','Venus','Mercury','Io','Titan']) < 0 ) { return; }

  // Test the unicode Symbol
  if (site==='de' && link.parentNode.id!=='coordinates') {
   mapbutton = $('<span>♁</span>').css('color','blue');
  } else {
   mapbutton = $('<img>').attr('src', wc.buttonImage).attr('srcset', wc.buttonImage + ' 1x, ' + wc.buttonImage2x + ' 2x');
  }
  mapbutton.addClass('wmamapbutton noprint').attr( {
   title: _msg('buttonTooltip'),
   alt: ''
  } )
  .on('mouseenter', function (){ $(this).css('opacity', 0.75); })
  .on('mouseleave', function () { $(this).css('opacity', ''); })
  .css('padding', rtl ? '0px 0px 0px 3px' : '0px 3px 0px 0px' ).css('cursor', 'pointer');

  if (wc.alwaysTooltips || ( wc.flowTextTooltips && $(link).parents('li, table, #coordinates').length===0)) {
   // insert tooltip rather than icon to improve text readability
   mapbutton = $('<span>').append(mapbutton).append('&nbsp;WikiMiniAtlas').css('cursor','pointer');
   var tooltip = $('<div>').css( {
    backgroundColor: 'white', padding: '0.2em', border: '1px solid black',
    position: 'absolute', top: '1em', left: '0em',
    display: 'none', zIndex : 15
   }).append(mapbutton);
   $(link).wrap(
    $('<span>')
     .css( { position: 'relative', whiteSpace: 'nowrap' } )
     .on('mouseleave', function () { tooltip.fadeOut(); })
    )
    .before(tooltip)
    .on('mouseenter', function () { tooltip.fadeIn(); });
  } else {
   // insert icon directly
   ws = $(link).css('whiteSpace');
   if (site!=='de' || link.parentNode.id!=='coordinates') {
    $(link).wrap( $('<span>').css('whiteSpace', 'nowrap') ).css('whiteSpace', ws).before(mapbutton);
   } else {
    $('#coordinates').append('<span class="noprint coordinates-separator"> | </span>').append(mapbutton);
   }
  }

  mapbutton.on( 'click', { param:
   marker.lat + '_' + marker.lon + '_' +
   wc.width + '_' + wc.height + '_' +
   site + '_' + zoomlevel + '_' + language + '&globe=' + globe }, showIFrame );

  // store coordinates
  coordinates = link.href;
  params = parseParams(link.href);
  coord_list.push( { lat: marker.lat, lon: marker.lon, obj: link, mb: mapbutton, title: params.title || params.pagename || '' } );
 } ); //end each

 var titlebutton = false;

 function addTitleButton( alat, alon, zoomlevel ) {
  mapbutton = $('<img>')
   .on('mouseenter', function (){ $(this).css('opacity', 0.75); })
   .on('mouseleave', function () { $(this).css('opacity', ''); })
   .css('padding', rtl ? '0px 3px 0px 0px' : '0px 0px 0px 3px' ).css('cursor', 'pointer')
   .attr('src', wc.buttonImage).attr('srcset', wc.buttonImage + ' 1x, ' + wc.buttonImage2x + ' 2x')
   .addClass('wmamapbutton noprint')
   .on( 'click', { param:
    alat + '_' + alon + '_' +
    wc.width + '_' + wc.height + '_' +
    site + '_' + zoomlevel + '_' + language
   }, showIFrame ); // zoomlevel!

  if (!titlebutton) {
   if ($('#coordinates').length) {
    $('#coordinates').find('img').detach();
    $('#coordinates').append(mapbutton);
   } else {
    $('<span id="coordinates"></span>').text(_msg('map')).append(mapbutton).appendTo('#bodyContent');
   }
   titlebutton = true;
  }
 }

 // detect and load KML
 // also insert globe even if no title coords are given
 (function () {
  var i, l = $('div.kmldata')
     ,alat = 0, alon = 0
     ,la1 = Infinity, la2 =- Infinity
     ,lo1 = Infinity, lo2 =- Infinity
     ,ex,ey, req;

  for (i=0; i<l.length; ++i) {// TODO: replace with .each
   coordinates = true;
   req = $.ajax({
    url: '/wiki/' + encodeURI(l.eq(i).attr('title')) + '?action=raw',
    dataType: 'xml',
    success: function (xml) {
     var zoomlevel;

     function processCoords(t) {
      var way = [], c, p = t.split(' '), i, lat, lon;
      for( i=0; i<p.length; ++i ) {
       c=p[i].split(',');
       if( c.length >= 2 ) {
        lat = parseFloat(c[1]);
        lon = parseFloat(c[0]);
        way.push( { lat: lat, lon: lon } );

        // determine extent of way
        if (lat<la1) { la1=lat; }
        if (lon<lo1) { lo1=lon; }
        if (lat>la2) { la2=lat; }
        if (lon>lo2) { lo2=lon; }
       }
      }
      return way;
     }

     // initialize transfer datastructure
     kml = { ways: [], areas: [] };

     // ways
     $(xml).find('LineString > coordinates').each(function () {
      var way = processCoords( $(this).text() );
      if (way.length>0) { kml.ways.push(way); }
     });

     // areas
     $(xml).find('Polygon').each(function () {
      var area = { inner: [], outer: [] };

      // outer boundary
      $(this).find('outerBoundaryIs > LinearRing > coordinates').each(function () {
       var way = processCoords($(this).text());
       if (way.length>0) { area.outer.push(way); }
      });

      // inner boundary (holes in the polygon)
      $(this).find('innerBoundaryIs > LinearRing > coordinates').each(function () {
       var way = processCoords($(this).text());
       if (way.length>0) { area.inner.push(way); }
      });

      // only add if we have an outer boundary
      if (area.outer.length>0) { kml.areas.push(area); }
     });

     // inset min/max extent
     kml.minlon = lo1;
     kml.maxlon = lo2;
     kml.minlat = la1;
     kml.maxlat = la2;

     // already got a request message
     if (mes!==null && kml.ways.length>0 && 'JSON' in window) {
      mes.postMessage(JSON.stringify(kml), document.location.protocol + wma_domain);
     }

     // insert blue globe
     if (coord_list.length===0 || (!$('#coordinates').find('.wmamapbutton').length)) {
      // determine center
      alat = (la1+la2)/2;
      alon = (lo1+lo2)/2;

      //determine zoomfactor
      ex = (lo2-lo1)/180.0 * 3.0*128;
      ey = (la2-la1)/180.0 * 3.0*128; // max extent in degrees, zoom0 has 3*128/180 px/degree
      for (zoomlevel=0; zoomlevel<12; ++zoomlevel) {
       if( ex>wc.width/2 || ey>wc.height/2 ) break;
       ex *= 2; ey *= 2;
      }

      // add mapbutton
      addTitleButton( alat, alon, zoomlevel );
     }
    }
   });
   // Add request promise to init array, and cast any errors to success so that
   // we don't abort init early when one of the requests failed. These are expected
   // to fail for titles we can't find.
   initPromises.push(req.then(null, function () { return $.Deferred().resolve(); } ));
  } // end for
 })();

 // detect "All Coordinates"
 links = $('#coordinates>span>a');
 if (links.length && links[0].href.indexOf('http://www.lenz-online.de/cgi-bin/wiki/wiki-osm.pl') === 0) {
   addTitleButton( 0, 0, 1 );
   coordinates = true;
 }

 // prepare iframe to house the map
 if (coordinates!==null) {
  wi.div = $('<div>').css( {
   width: (wc.width+2)+'px', height: (wc.height+2)+'px',
   margin: '0px', padding: '0px',
   backgroundColor : 'white', border: '1px solid gray',
   position: 'absolute', top: '1em', zIndex: 13, boxShadow: '3px 3px 25px rgba(0,0,0,0.3)'
  } ).css( rtl ? 'left' : 'right', '2em' ).hide();

  var rbrtl = [ '//upload.wikimedia.org/wikipedia/commons/b/b5/Button_resize.png',
                '//upload.wikimedia.org/wikipedia/commons/3/30/Button_resize_rtl.png' ];
  wi.resizebutton = $('<img>').attr( {
   title : _msg('resize'),
   src : rbrtl[rtl?1:0]
  } ).hide().attr('ondragstart','return false');

  // cover the iframe to prevent loosing the mouse to the iframe during resizing
  wi.resizehelper = $('<div>').css( { position: 'absolute', top:0, left:0, zIndex: 20 } ).hide();

  wi.closebutton = $('<img>').attr( {
   title : _msg('close'),
   src : '//upload.wikimedia.org/wikipedia/commons/d/d4/Button_hide.png'
  } ).css( {
   zIndex : 15, position : 'absolute', right : '11px', top : '9px', width : '18px', cursor : 'pointer'
  } ).click( function(e) { wi.div.hide(); } );

  wi.iframe = $('<iframe>')
   .attr( { scrolling: 'no', frameBorder : 0 } )
   .css( {
    zIndex: 14, position: 'absolute', right: '1px', top: '1px',
    width: (wc.width)+'px', height: (wc.height)+'px',
    margin: '0px', padding: '0px'
   } );

  wi.div.append(wi.iframe);
  wi.div.append(wi.resizehelper);
  wi.div.append(wi.closebutton);
  (function () {
   var idle = true, dir = rtl?-1:1;
   function adjusthelper() {
    wi.resizehelper.css( { width: (wc.width+2)+'px', height: (wc.height+2)+'px' } );
   }
   wi.div.append(
    $('<div>')
     .css( {
       zIndex : 15, position : 'absolute', bottom : '3px',
       width : '18px', height: '18px', cursor : (rtl?'se-resize':'sw-resize'),
       'user-select': 'none', '-moz-user-select': 'none', '-ms-user-select': 'none'
      } ).css( (rtl?'right':'left'), '3px' )
     .on('mouseenter', function(e) { wi.resizebutton.fadeIn(); } )
     .on('mouseleave', function(e) { if( idle ) { wi.resizebutton.fadeOut(); } } )
     .on('mousedown', function(e) {
       if (idle) {
        var lastx = e.pageX, lasty = e.pageY;
        wi.resizehelper.show();
        adjusthelper();

        $('body')
         .on('mouseup.wmaresize', function(e) {
          $('body').off('mousemove.wmaresize');
          $('body').off('mouseup.wmaresize');
          idle = true;
          wi.resizehelper.hide();
         } )
         .on('mousemove.wmaresize', function(e) {
          wc.width -= dir*(e.pageX-lastx);
          wc.height += (e.pageY-lasty);
          lastx = e.pageX; lasty = e.pageY;
          wi.div.css( { width: (wc.width+2)+'px', height: (wc.height+2)+'px' } );
          wi.iframe.css( { width: wc.width+'px', height: wc.height+'px' } );
          adjusthelper();
         } );

        idle = false;
       }
      } )
     .append(wi.resizebutton)
   );
  })();

  $(window).on('message', messageHub);

  // Fire event for other code to extend or integrate with WMA
  if (initPromises.length) {
    $.when.apply( null, initPromises ).then(function () {
      mw.hook('WikiMiniAtlas.load').fire();
    } );
  } else {
    mw.hook('WikiMiniAtlas.load').fire();
  }
 }
});

// </nowiki>