

//window.onerror = function(msg, url, line, col, error) {
//    alert("Chyba: " + msg + "\\nRiadok: " + line);
//};

(function () {
console.log('Start ForGME');

var map = document.getElementById('cacheDetailsTemplate');
if((map !== null)&&(map.innerHTML.indexOf('<span>Route to</span>')==-1))
{if(map !== null) {map.innerHTML = map.innerHTML.replace('{{#if $ctx.userIsLoggedIn() }}','{{#if $ctx.userIsLoggedIn() }}<a class="lnk route" href="/route" target="_blank"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAAYCAIAAACeHvEiAAAABnRSTlMA/wD/AP83WBt9AAAACXBIWXMAAA3/AAAN/wH0irKJAAAEIElEQVQ4jaVUb2xTVRQ/975/bdfS7l/XdoV1blOmYxkyEGYVKUTUGMPABJ0bui8komKCnwyExMS4j34QMWokQMgGEpwZWUTM6kgdohCnyIx06/52s2+b2+v6ute9vnevH9q0azM/cXK/3HN/53fP/Z1zLqKUwgMbfnAKAGD/70DS6F+yHpB0KUkxAjuPfEVstYkxrnXvGiwJAh1jia6IOrxMVvsxggYL8+4G4TUHz6CcEJSny50lve1e/O94TnxOAICviD1fZ3IJ2axyWO7J8+1DU6JKAUAAUjL+72wUbdxYMzR032azugrjk0XWJcoAwGYL82VtlV0w57MsJOPHBi9NxRcAIcFc8DwjKb3y9z8Gjxx54+zZr1lGeL25XN7MdiaLVDlOCd1WWPFBfTOPWVhdozPhn8PKItE0quvrQPOEwrJqnZkRu7u/kxZjk5PTouxojM7ZkE4JIZp2W5q8NjeUo+7oRAhfufIC1VJbDujANJsAmVLa3n7wi88vjoyMD4/NkTjThAZVSGs7MhhW3uwwGgxplm97+ju7wpRShBAA6ET3eh/v7w8AQFdXjyjOA8Avt36fr674824khUlZXcOdZ3d5WQDQCdm1s+nRmurg/VHf7if9fQPnzl+WpGgyqSGEHqrcEJ4SYzF5eVkptFnLyx3HT7wjCFxXZ0/bof2Iw2l1l5XE7j0tqqJmbqjwOCUpOjMT4Vj+k1Mffnb6wsjIOABUVVUwDA4GxzLI2k01F859jAEAKAWqczzmeCzwiJBkY2N9JCICAMtyodCEoiTS8o1O1tfXCjwr8CiFJ1oyrS7H48MnagHAgnRPMv5NoMBgEAihDMNizJz56rKqptOklJbaiw+8+NjexugwNUiUtZnL0pXWEe4xO7sKSqjbqiia95m9V6/+AAAsywPAyZNHPR535gn+voGaOi9CYHJbLprtAYsjzcJjdpOrxm017mGigbsMy3GRyCxCiGVYABAMPMbZtgoGx0rsZT/9gbdjucrMNJRWplkwQlvXufczC/9MxV3V3uvXb1BKMV573Cmlfv9NY+kT0QX1ZV5qsnmyvft0YfVTPOkNxBq3bhkYuJ3Cp44SSoKQnOH0993ctmP7jd/ULaaSqgJ7tnetnEnkd+gGLhSaWFyMAgAhOgWKAHV0nM7UKGVLS7GZaXFWqeSLfQhhWD1HVufOV1rburuvZTJX1QQAtLTsK3OU5j2qt9d/sLXNaK1NebIsBoNQai8mVM94NC2ZWFl++BGP0WgglGQWIGp3FK2mzvn/CkymT0991HroQGZSdF0jhKysxBVFTi3MkLfebnvv2GGOzcqfXwiLxXz8/aP7Xnqu82L3r7cGRXE+JbMg8O71Tp/P2/Jqs9Npz4vK/zFXWywmT09HXK4yUZyjAB7Pep7j1kT+Bx6E4ArnM2VZAAAAAElFTkSuQmCC"><span>Route to</span></a>\
<a class="lnk showwpt" href="/showwpt" target="_blank"><img src="https://www.geocaching.com/images/wpttypes/pins/452.png"><span>Wpts</span></a>\
<a class="lnk streetview" href="/streetview" target="_blank"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAAYCAIAAACTAIFlAAAACXBIWXMAAA3/AAAN/wH0irKJAAACaUlEQVQ4jZVTy0tUURj/nXMfw8hojb3EMMqQyJJcVotqVwSKBOUiXPSACiJsV/9ALVr12EYtAheVFEFQtOmphRSplFZWoE2T4+jo3Ln3zpx7ztfCe++8pPCsPr7z/c7vwXcYEWGZhy8XAECvbingse0N5r24xo7FzHrO/s/zJOc9tMS5ush6zi/OuLJaO1Wd3qT9yZWL9eHJ3IJUFQNL8HAJV/mP5wUqlVX4kYQ3lpx10TGe219n/CiolFD30t7Blfpao4hlYdYEXJ7MW4o66w0joCdgwlF3Z8SN5miDGcBClSOWd3rc9irFExE9z3gXvjlL+PlqqY64rjH0/xGzwie/kxCuws5azSpQ4LEkayFRwxmAd3My6/n3L9KeUGRyQCLMvCQ3gt+WKN7LoFAlwYbVKp29TcmZPCUtqtN9u406H0rL8QUFD+E+FDG7V2uuQM9re2uMx4OIzraYpwadq2P5E5vMYtil+SiiK8PurS95IhpKeYvNtv6sKA+zbA8YoJEvfSDpW2Ee9PJdqNodGdgNTYvKkSqMCqbDxLx/YhTBcit5pIBdTuXv6FBC9o2KyaxKWHSy3SjFZLJ0/qkznaPuVqNzi15jMB3A9YHCSEr27jI3rOC3PwglAWDeJltQVGeNUXbtQNQW1Dcseu47N7uiOoDRpDy6w2hdowE4ss0488D5naFHY2IsKdfF+PF2M6IhorHu7carCW/eJUZEiQV16VlhLqf2btab4twWxBn2NOufp+XPWWqoZfMOvfwu0w4dajO62nT//yjCVEa9n5Iff6lcnjQODhAgCSA0xfm+Fm1jvRaLAMBfT6aexLuPdvMAAAAASUVORK5CYII="><span>StreetView</span></a>\
<a class="lnk skmapycz" href="/skmapycz" target="_blank" title="Foto na mapy.cz"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAQCAIAAABGNLJTAAAAK3RFWHRDcmVhdGlvbiBUaW1lAJp0IDEwIGF1ZyAyMDIzIDEyOjIxOjIyICswMTAwaMhOPQAAAAd0SU1FB+cICgoVOxNxoNkAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAEZ0FNQQAAsY8L/GEFAAABKElEQVR42mP8//8/A9GACZnztr3rSUjUn1evcSr/jwRuSSlC0NveCf9Rwb/fv4EkE1Yj3s+ej2Liz5+PnD1/nDvPiOzu29JKcLbq03sQxu8HDx+5ef/7+g3d3cjgy45dEMbztGyIUuyqmYUEQYqSM/7/+QNU+vPqNexhAgHSKxYzsjCDNCSkftm6HXsIAr0CYbBra8nt3QFkfN1/EEjKrF8l1tGMrvr91BlwNpuKMpDk9fdVvnWZ08yEkZ0dIs4CV/F1/yEgCXEDEIhP6uMLDsAel+9nzwMGJ5Ah1t0OEUFWyqaujqL6y/qNIA4fH9B2TH+za6ihqP5x8TKQlNu+Ee5EZAARZJWVAbn736dPEFFWBXlckSWUn8NhagxKVS8KSr+fPfefCAAA3kCtwkV1TNQAAAAASUVORK5CYII="><span>sk.mapy.cz</span></a>\
<a class="lnk skmapycz" href="/freemapsk" target="_blank" title="Foto na freemap.sk"><img src="data:image/gif;base64,R0lGODdhAQABAIABAAAAABOE4CwAAAAAAQABAAACAkwBADs=">🌍<span>FreeMapSk</span></a>\
<a class="lnk peakfinder" href="/peakfinder" target="_blank" title="PeekFinder"><img src="data:image/gif;base64,R0lGODdhAQABAIABAAAAABOE4CwAAAAAAQABAAACAkwBADs=">🧭<span>PeakFinder</span></a>\
<a class="lnk peakfinder" href="/streetpeak" target="_blank" title="StreetPeak"><img src="data:image/gif;base64,R0lGODdhAQABAIABAAAAABOE4CwAAAAAAQABAAACAkwBADs=">🏔<span>StreetPeak</span></a>').replace('Pridať do Zoznamu', 'AddToList').replace('Stiahnuť GPX', 'DownGPX').replace('Zaloguj sa', 'LogIt').replace('Send to c:geo', 'Toc:geo').replace(/..\/images\/stars\/stars/g,'https://mozilive.zubor.net/ikonky/stars')}}
    var global_activ_username = '' ;
    var global_me = '' ;
    var global_vips = false;//getValue("vips", false);    
    var global_img_vip_on="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAKCAYAAAC9vt6cAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sHDhE0Aq4StvMAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAzklEQVQoz6WSwQvBcBTHP7/lanFT3DdzV9yw+RNc8E/s6A/YSa6KUrs4u4omB6KUKJoc5a+Q5rRlOCz7Xl7feu/zXu89AXjEUAKgszb/KrbKPSTfDJo2t8MdgNvhzrBlB0l+tMo9+o0R+8kxgASAgqFynrsAnGYumqF+deysTepmhZW9/QZouoLrXHk+nlwWVzRd+TnytOtQahfDOwBI51LImSTLwQo5I5POpn5O8Cnp3WiGyma8o1BXIi8yDKgpCEmQr0YHCMCLc0YR95Fe0bc6eQ97MqYAAAAASUVORK5CYII=";
    var global_img_vup_on="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAKCAIAAAA2KZn2AAAABnRSTlMA/wD/AP83WBt9AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAsklEQVR4nGNgIAswMjAw/N+5nTQ97p5MEJZOUcm6L98YGBjWffmmW1wKkUMmGd091XLysjduhqiHarO3t9+3bx8DA8PevXvt7Owwbfi/c3tHR8eWLVtQtDk7O69Zs4aBgWHt2rXOzs5YHVZRUeHj4wPhskCoIB6uDjm58r375eXlg3i4sNqGzGWCsyIjI3t6eiIjIwkECJq2Qm1NJiamAi0NCLesrAwSHlgBmRFAknoEAAAAUjSNJTSZCwAAAABJRU5ErkJggg==";
    var gclh_del_vip=false;
    var gclh_del_vup= false;
    var global_img_vip_off="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAKCAYAAAC9vt6cAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB9sHDhEzBX83tZcAAAAZdEVYdENvbW1lbnQAQ3JlYXRlZCB3aXRoIEdJTVBXgQ4XAAAAsElEQVQoz6WSsQ2DUAxEz4gdfkdBQQUlDAU9E0ALHQWLsMAfA8o/BNVLkYCS0ETkGstn6+kk2yShPxRLEtxjmJmio8nzXN57SZL3XkVRnEtHNTNlWaZ5nj9AAHRdR9M0ANR1Td/38Iz2UZdlIUmS0zsB67rinGPfd5xzbNt2AUgiTVOmaboCAMqypG1bqqo6ve8E77oAhmEgiiLGcbwHCCEQxzEhhJ8B9hrcPqP9+0gPbh/tf/c8szwAAAAASUVORK5CYII=";
    var global_img_vup_off="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAKCAAAAACcIFF9AAAACXBIWXMAAA7EAAAOxAGVKw4bAAAAAnRSTlMA/1uRIrUAAABNSURBVAjXY2DAAj6gAZCQ9uEPh3U+MIAgg2oWWCgr+0NWFkTow3Y5sNBh8Q/ih1FVfTAtM/sAVQU160MfUz+60AcWIC5jQBFCdwQGAABlylaI66CZYAAAAABJRU5ErkJggg==";
//    var gclh_add_vip=false;
//    var gclh_add_vup=false;
    var global_copy_icon="data:image/png;base64, "
    var glnk="";  
	var gccode="";  
	var side="";  
	var guid="";  
	var username="";  
    var settings_primary_elevation_service=1;
    var settings_secondary_elevation_service=0;
    var settings_distance_units = "Metric";
	
	function gclh_add_vip() {
                [global_vips, global_vups] = gclh_add_vipvup(this.name, global_vips, "vip", global_vups, "vup");
                gclh_build_vip_list();
                setLinesColorVip(this.name);
            }
    function gclh_add_vup() {
                [global_vups, global_vips] = gclh_add_vipvup(this.name, global_vups, "vup", global_vips, "vip");
                gclh_build_vip_list();
                setLinesColorVip(this.name);
            }	
function is_page(name) {
    var status = false;
    var url = document.location.pathname;
    if (name == "cache_listing") {
        if (url.match(/^\/(seek\/cache_details\.aspx|geocache\/)/) && !document.getElementById("cspSubmit") && !document.getElementById("cspGoBack")) status = true;
        // Exclude (new) Log Page
        if (url.match(/^\/(geocache\/).*\/log/)) status = false;
        // Exclude unpublished Caches
        if (document.getElementsByClassName('UnpublishedCacheSearchWidget').length > 0) status = false;
    } else if (name == "unpublished_cache") {
        if (document.getElementById("unpublishedMessage") !== null || document.getElementById("ctl00_ContentBody_GeoNav_uxPostReviewerNoteLogType") !== null) status = true;
    } else if (name == "profile") {
        if (url.match(/^\/my(\/default\.aspx)?/)) status = true;
    } else if (name == "publicProfile") {
        if (url.match(/^\/(profile|p\/)/)) status = true;
    } else if (name == "lists") {
        if (url.match(/^\/plan\/lists/)) status = true;
    } else if (name == "searchmap") {
        if (url.match(/^\/play\/map/)) status = true;
    } else if (name == "map") {
        if (url.match(/^\/map/)) status = true;
    } else if (name == "find_cache") {
        if (url.match(/^\/play\/(search|geocache)/)) status = true;
    } else if (name == "collection_1") {
        if (url.match(/^\/play\/(friendleague|leaderboard|souvenircampaign|guidelines)/)) status = true;
    } else if (name == "hide_cache") {
        if (url.match(/^\/play\/hide/)) status = true;
    } else if (name == "geotours") {
        if (url.match(/^\/play\/geotours/)) status = true;
    } else if (name == "drafts") {
        if (url.match(/^\/account\/drafts/)) status = true;
    } else if (name == "settings") {
        if (url.match(/^\/account\/(settings|lists|drafts|documents)/)) status = true;
    } else if (name == "messagecenter") {
        if (url.match(/^\/account\/messagecenter/)) status = true;
    } else if (name == "dashboard") {
        if (url.match(/^\/account\/dashboard$/)) status = true;
    } else if (name == "owner_dashboard") {
        if (url.match(/^\/play\/owner/)) status = true;
    } else if (name == "dashboard-section") {
        if (url.match(/^\/account\/dashboard/)) status = true;
    } else if (name == "promos") { // Like 'Wonders of the World'.
        if (url.match(/^\/promos/)) status = true;
    } else if (name == "track") {
        if (url.match(/^\/track\/($|#$|edit|upload|default.aspx)/)) status = true;
    } else if (name == "souvenirs") {
        if (url.match(/^\/my\/souvenirs\.aspx/)) status = true;
    } else {
        gclh_error("is_page", "is_page("+name+", ... ): unknown name");
    }
    return status;
    }    
    function formatElevation(elevation) {
                return ((elevation>0)?"+":"")+((settings_distance_units != "Imperial")?(Math.round(elevation) + "m"):(Math.round(elevation*3.28084) + "ft"));
    }
    function gclh_error(modul, err) {
    console.log(modul, err);
    } 
    function gclh_log(msg) {
    console.log(msg);
    } 
    /*
    var elevationServicesData = [
        { "function": undefined, 'name': 'no' },
        { "url" : "https://api.open-elevation.com/api/v1/lookup?locations={locations}", "function": undefined, 'name': 'Open-Elevation' }
//        { "url" : "http://localhost:54386/elevation?locations={locations}", "function": undefined, 'name': 'Open-Elevation' }		
       
    ];
	*/
	function elevationServicesDataInit(c) {
    c.elevationServicesData = [
        { "function": undefined, 'name': 'no' },
        { "url" : "https://api.open-elevation.com/api/v1/lookup?locations={locations}", "function": undefined, 'name': 'Open-Elevation' },
//		{ "url" : "http://localhost:54388/elevation?locations={locations}", "function": undefined, 'name': 'Open-Elevation' },
        { "url" : "https://maps.googleapis.com/maps/api/elevation/json?sensor=false&locations={locations}", "function": undefined, 'name': 'Google Elevation' },
        { "url" : "http://api.geonames.org/astergdemJSON?{locations}", "function": undefined, 'name': 'Geonames-Elevation' }
    ];
	}
	elevationServicesDataInit(window);
            elevationServicesData[1]['function'] = addElevationToWaypoints_OpenElevation;
            
            function addElevationToWaypoints_OpenElevation(responseDetails) {
                try {
//                    alert(responseDetails.responseText);
					json = JSON.parse(responseDetails.responseText);
                    var elevations = [];                    
                    elevations.push(json.results[0].elevation);
                    document.getElementById('elevation-waypoint-NaN').innerText=formatElevation(elevations[0])+ " | ";
                    $("#elevation-waypoint-NaN").attr('title','Elevation data from OpenElevation'); 

                } catch(e) {
					alert('Error:'+responseDetails.responseText);
                    gclh_log( 'Error',responseDetails.responseText );
                }
            }
            var elevationServices = [];
            if (settings_primary_elevation_service > 0) {
                elevationServices.push(elevationServicesData[settings_primary_elevation_service]);
            }
            if (settings_secondary_elevation_service > 0) {
                elevationServices.push(elevationServicesData[settings_secondary_elevation_service]);
            }

            // This function can be re-entered.
                    function getElevations(serviceIndex,locations) {
                if (serviceIndex >= elevationServices.length || elevationServices < 0) {
                    $('.waypoint-elevation').each(function (index, value) {
                        $(this).html('<span title="Fail to load elevation data">???</span>');
                    });
                    return;
                }
                $('.waypoint-elevation').each(function (index, value) {
                    $(this).html('<img src="data:image/gif;base64,R0lGODlhEAALAPQAAP///wAAANra2tDQ0Orq6gYGBgAAAC4uLoKCgmBgYLq6uiIiIkpKSoqKimRkZL6+viYmJgQEBE5OTubm5tjY2PT09Dg4ONzc3PLy8ra2tqCgoMrKyu7u7gAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCwAAACwAAAAAEAALAAAFLSAgjmRpnqSgCuLKAq5AEIM4zDVw03ve27ifDgfkEYe04kDIDC5zrtYKRa2WQgAh+QQJCwAAACwAAAAAEAALAAAFJGBhGAVgnqhpHIeRvsDawqns0qeN5+y967tYLyicBYE7EYkYAgAh+QQJCwAAACwAAAAAEAALAAAFNiAgjothLOOIJAkiGgxjpGKiKMkbz7SN6zIawJcDwIK9W/HISxGBzdHTuBNOmcJVCyoUlk7CEAAh+QQJCwAAACwAAAAAEAALAAAFNSAgjqQIRRFUAo3jNGIkSdHqPI8Tz3V55zuaDacDyIQ+YrBH+hWPzJFzOQQaeavWi7oqnVIhACH5BAkLAAAALAAAAAAQAAsAAAUyICCOZGme1rJY5kRRk7hI0mJSVUXJtF3iOl7tltsBZsNfUegjAY3I5sgFY55KqdX1GgIAIfkECQsAAAAsAAAAABAACwAABTcgII5kaZ4kcV2EqLJipmnZhWGXaOOitm2aXQ4g7P2Ct2ER4AMul00kj5g0Al8tADY2y6C+4FIIACH5BAkLAAAALAAAAAAQAAsAAAUvICCOZGme5ERRk6iy7qpyHCVStA3gNa/7txxwlwv2isSacYUc+l4tADQGQ1mvpBAAIfkECQsAAAAsAAAAABAACwAABS8gII5kaZ7kRFGTqLLuqnIcJVK0DeA1r/u3HHCXC/aKxJpxhRz6Xi0ANAZDWa+kEAA7AAAAAAAAAAAA" title="Load elevation data for the waypoint from '+elevationServices[serviceIndex]['name']+'."/>');
                });
                $('.waypoint-elevation-na').each(function (index, value) {
                    $(this).html('n/a');
                });
                var additionalListingIndex = 0;
                if (elevationServices[serviceIndex].name == "Geonames-Elevation") {
                    var maxLocations = 20;
                    var countLocations = 0;
                    var lats = "";
                    var lngs = "";
                    for (var i=0; i<locations.length; i++) {
                        countLocations++;
                        var latlng = locations[i].split(",");
                        lats += (lats == "" ? latlng[0] : ","+latlng[0]);
                        lngs += (lngs == "" ? latlng[1] : ","+latlng[1]);
                        if (countLocations == maxLocations || i == (locations.length - 1)) {
                            var locationsstring = "lats="+lats+"&lngs="+lngs+"&username=gclh";
                            getElevationsPackage();
                            additionalListingIndex = additionalListingIndex + maxLocations;
                            countLocations = 0;
                            lats = "";
                            lngs = "";
                        }
                    }
                } else {
                    var locationsstring = locations.join('|');
                    getElevationsPackage();
                }
                function getElevationsPackage() {
                    GM_xmlhttpRequest({
                        method: 'GET',
                        url: elevationServices[serviceIndex].url.replace('{locations}',locationsstring),
                        context: {
                            retries : serviceIndex,
                            serviceName : elevationServices[serviceIndex]['name'],
                            locations : locations,
                            additionalListingIndex : additionalListingIndex
                        },
                        onload: elevationServices[serviceIndex]['function'],
                        onerror: function(responseDetails) {
                            var context = responseDetails.context;
//                            gclh_error("getElevations("+context.serviceName+")", { 'message': 'GM_xmlhttpRequest() reported error.', 'stack': '' });
                            console.log(responseDetails); // workaround gclh_log doesn't work for responseDetails. Error message 'TypeError: Function.prototype.toString called on incompatible object'
                            getElevations(context.retries+1,context.locations);
                        },
                        onreadystatechange: function(responseDetails) {
                        },
                        ontimeout: function(responseDetails) {
                            var context = responseDetails.context;
                            gclh_error("getElevations("+context.serviceName+")", { 'message': 'GM_xmlhttpRequest() reported timeout.', 'stack': '' });
                            console.log(responseDetails); // workaround gclh_log doesn't work for responseDetails. Error message 'TypeError: Function.prototype.toString called on incompatible object'
                            getElevations(context.retries+1,context.locations);
                        },
                        onabort: function(responseDetails) {
                            var context = responseDetails.context;
                            gclh_error("getElevations("+context.serviceName+")", { 'message': 'GM_xmlhttpRequest() reported abort.', 'stack': '' });
                            console.log(responseDetails); // workaround gclh_log doesn't work for responseDetails. Error message 'TypeError: Function.prototype.toString called on incompatible object'
                            getElevations(context.retries+1,context.locations);
                        },
                    });
                }
            }
    function toDec(coords) {
        var match = coords.match(/([0-9]+)°([0-9]+)\.([0-9]+)′(N|S), ([0-9]+)°([0-9]+)\.([0-9]+)′(W|E)/);
        if (match) {
            var dec1 = parseInt(match[1], 10) + (parseFloat(match[2] + "." + match[3]) / 60);
            if (match[4] == "S") dec1 = dec1 * -1;
            dec1 = Math.round(dec1 * 10000000) / 10000000;
            var dec2 = parseInt(match[5], 10) + (parseFloat(match[6] + "." + match[7]) / 60);
            if (match[8] == "W") dec2 = dec2 * -1;
            dec2 = Math.round(dec2 * 10000000) / 10000000;
            return new Array(dec1, dec2);
        } else {
            match = coords.match(/(N|S) ([0-9]+)°? ([0-9]+)\.([0-9]+)′?'? (E|W) ([0-9]+)°? ([0-9]+)\.([0-9]+)/);
            if (match) {
                var dec1 = parseInt(match[2], 10) + (parseFloat(match[3] + "." + match[4]) / 60);
                if (match[1] == "S") dec1 = dec1 * -1;
                dec1 = Math.round(dec1 * 10000000) / 10000000;
                var dec2 = parseInt(match[6], 10) + (parseFloat(match[7] + "." + match[8]) / 60);
                if (match[5] == "W") dec2 = dec2 * -1;
                dec2 = Math.round(dec2 * 10000000) / 10000000;
                return new Array(dec1, dec2);
            } else {
                match = coords.match(/(N|S) ([0-9]+) ([0-9]+) ([0-9]+)\.([0-9]+) (E|W) ([0-9]+) ([0-9]+) ([0-9]+)\.([0-9]+)/);
                if (match) {
                    var dec1 = parseInt(match[2], 10) + (parseFloat(match[3]) / 60) + (parseFloat(match[4] + "." + match[5]) / 3600);
                    if (match[1] == "S") dec1 = dec1 * -1;
                    dec1 = Math.round(dec1 * 10000000) / 10000000;
                    var dec2 = parseInt(match[7], 10) + (parseFloat(match[8]) / 60) + (parseFloat(match[9] + "." + match[10]) / 3600);
                    if (match[6] == "W") dec2 = dec2 * -1;
                    dec2 = Math.round(dec2 * 10000000) / 10000000;
                    return new Array(dec1, dec2);
                } else {
                    match = coords.match(/(N|S) ([0-9]+) ([0-9]+) ([0-9]+\..[0-9].) (E|W) ([0-9]+) ([0-9]+) ([0-9]+\..[0-9].)/);
                    if (match) {
                        var dec1 = parseInt(match[2], 10) + (parseFloat(match[3]) / 60) + (parseFloat(match[4]) / 3600);
                        if (match[1] == "S") dec1 = dec1 * -1;
                        dec1 = Math.round(dec1 * 10000000) / 10000000;
                        var dec2 = parseInt(match[6], 10) + (parseFloat(match[7]) / 60) + (parseFloat(match[8]) / 3600);
                        if (match[5] == "W") dec2 = dec2 * -1;
                        dec2 = Math.round(dec2 * 10000000) / 10000000;
                        return new Array(dec1, dec2);
                    } else return false;
                }
            }
        }
    }   
//    function getFavScore(gccode, userToken) {
//       $.ajax({
//           type: "POST",
//           cache: false,
//           url: '/datastore/favorites.svc/score?u=' + userToken,
//           success: function (scoreResult) {
//               var score = 0;
//               if (scoreResult) score = scoreResult;
//               if (score > 100) score = 100;
//               var id = '#popup_additional_info_' + gccode + ' .favi_points';
//               if ($(id)[0] && $(id)[0].childNodes[1]) $(id)[0].childNodes[1].data = " "+score+"%";
//           }
//       });
//    }
	function getFavoriteScore(gccode, func) {
        $.ajax({
            type: "GET",
            cache: false,
            url: '/api/proxy/web/v1/geocache/'+gccode+'/favoritepoints/score',
            success: function(scoreResult) {
                var score = 0;
                if (scoreResult) score = scoreResult;
                if (score > 100) score = 100;
                func(score);
            }
        });
    }	
    function addCopyToClipboardLink(element_to_copy, anker_element, title, style){
        try {
			anker_element= null;
			title=""; style= "";
            var ctoc = false;
            var span = document.createElement('span');
            span.setAttribute("class",'ctoc_link');
            span.innerHTML = '<a class="ctoc_link" href="javascript:void(0);"><img src="'+global_copy_icon+'" title="Copy ' + title + ' ' + 'to clipboard" style="vertical-align: text-top;"> </a>';
            if(style != ""){
                span.setAttribute("style", style);
            }
            if(!anker_element) anker_element = element_to_copy;
			if (!anker_element.parentNode) return;
//			console.log('255-anker_element='+anker_element);
            anker_element.parentNode.insertBefore(span, anker_element.nextSibling);

            appendCssStyle(".ctoc_link:link {text-decoration: none ;}", null, 'ctoc_link_style_id');

            span.addEventListener('click', function() {
                // Tastenkombination Strg+c ausführen für eigene Verarbeitung.
                ctoc = true;
                document.execCommand('copy');
            }, false);
            document.addEventListener('copy', function(e){
                // Normale Tastenkombination Strg+c für markierter Bereich hier nicht verarbeiten. Nur eigene Tastenkombination Strg+c hier verarbeiten.
                if (!ctoc) return;
                // Gegebenenfalls markierter Bereich wird hier nicht beachtet.
                e.preventDefault();
                // Copy Data wird hier verarbeitet.
                if (typeof element_to_copy === 'string' || element_to_copy instanceof String){
                    e.clipboardData.setData('text/plain', element_to_copy);
                }else{
                    e.clipboardData.setData('text/plain', element_to_copy.innerHTML);
                }
                animateClick(span);
                ctoc = false;
            });
        } catch(e) {console.log("Copy to clipboard",e);}
    }
	// Search in array.
    function in_array(search, arr) {
        for (var i = 0; i < arr.length; i++) {if (arr[i] == search) return true;}
        return false;
    }
    function caseInsensitiveSort(a, b) {
        var ret = 0;
        a = a.toLowerCase();
        b = b.toLowerCase();
        if (a > b) ret = 1;
        if (a < b) ret = -1;
        return ret;
    }
            // Build VIP, VUP, Mail Icons.
            // ----------
			function gclh_build_vipvup(user, ary, desc, link) {
                if (link == undefined) {
                    var link = document.createElement("a");
                    var img = document.createElement("img");
                    link.appendChild(img);
                } else var img = link.childNodes[0];
                img.setAttribute("class", "gclh_"+desc);
                img.setAttribute("border", "0");
                link.setAttribute("href", "javascript:void(0);");
                link.setAttribute("name", user);
                if (in_array(user, ary)) {
                    img.setAttribute("src", (desc == "vip" ? global_img_vip_on : global_img_vup_on));
                    img.setAttribute("title", "Remove " + user + " from " + desc.toUpperCase() + "-List");
                    link.addEventListener("click", (desc == "vip" ? gclh_del_vip : gclh_del_vup), false);
                } else {
                    img.setAttribute("src", (desc == "vip" ? global_img_vip_off : global_img_vup_off));
                    img.setAttribute("title", "Add " + user + " to " + desc.toUpperCase() + "-List");
                    link.addEventListener("click", (desc == "vip" ? gclh_add_vip : gclh_add_vup), false);
                }
                return link;
            }


            function gclh_build_vipvupmail(side, user) {
                if (side && user && user != "") {
                    link = gclh_build_vipvup(user, global_vips, "vip");
                    side.appendChild(document.createTextNode(" "));
                    side.appendChild(link);
                    if (settings_process_vup && user != global_activ_username) {
                        link = gclh_build_vipvup(user, global_vups, "vup");
                        side.appendChild(document.createTextNode(" "));
                        side.appendChild(link);
                    }
                    buildSendIcons(side, user, "per u");
                }
            }

    function getOwnBMLs(content) {
        var count = 0;
        var text = '';
        var ary = [];
        var list = '';
        $(content).find('ul.BookmarkList li').each(function() {
            if ( $(this).find('a[href*="/profile/?guid="], a[href*="/p/?guid="]')[0] && $(this).find('a[href*="/profile/?guid="], a[href*="/p/?guid="]')[0].innerHTML.match(global_me) &&
                 $(this).find('a[href*="/bookmarks/view.aspx?guid="]')[0] && $(this).find('a[href*="/bookmarks/view.aspx?guid="]')[0].innerHTML                                           ) {
//                if (!ary.includes($(this).find('a[href*="/bookmarks/view.aspx?guid="]')[0].innerHTML)) {
				if (!ary.indexOf($(this).find('a[href*="/bookmarks/view.aspx?guid="]')[0].innerHTML)) {
                    count++;
                    ary.push($(this).find('a[href*="/bookmarks/view.aspx?guid="]')[0].innerHTML);
                }
            }
        });
        ary.sort(caseInsensitiveSort);
        for (var i = 0; i < ary.length; i++) {
            list += (list == '' ? '' : '\n') + ary[i];
        }
        text = 'Currently available in ' + count + (count == 1 ? ' own list' : ' own lists');
        return [count, text, list];
    }    
    function buildSendIcons(b_side, b_username, b_art, guidSpecial) {
        if (b_art == "per guid") {
            // guid aus besonderen Proceduren (zB: post cache log new page).
            if (guidSpecial) guid = guidSpecial;
            if (guid == "" || guid == undefined) return;
            if (guid.match(/\#/)) return;
            // Keine Verarbeitung für Stat Bar.
            if (b_side.innerHTML.match(/https?:\/\/img\.geocaching\.com\/stats\/img\.aspx/)) return;
        } else {
            if (b_username == "") return;
        }
        if (b_side == "" || b_side == undefined || b_username == undefined || global_activ_username == "" || global_activ_username == undefined || b_username == global_activ_username) return;
        // Wenn Owner, dann echten Owner setzen und nicht gegebenenfalls abweichenden Owner aus Listing "A cache by".
        if (b_side.parentNode.id == "ctl00_ContentBody_mcd1") {
            var owner = get_real_owner();
            b_username = owner;
        }
        // Wenn User "In the hands of ..." im TB Listing, prüfen ob aktiver Username dort enthalten ist und Mail, Message nicht erzeugen.
        var username_send = b_username;
        if (b_side.id == "ctl00_ContentBody_BugDetails_BugLocation") {
            if (b_username.match(global_activ_username)) return;
            b_username = "";
            username_send = "user";
        }
        // Message, Mail Template aufbauen.
        template_message = urlencode(buildSendTemplate());
        template = urlencode(buildSendTemplate().replace(/#Receiver#/ig, b_username), convertPlus = false);
        // Message Icon erzeugen.
        if (settings_show_message && b_art == "per guid") {
            var mess_link = document.createElement("a");
            var mess_img = document.createElement("img");
            mess_img.setAttribute("style", "margin-left: 0px; margin-right: 0px");
            mess_img.setAttribute("title", "Send a message to " + username_send);
            mess_img.setAttribute("src", global_message_icon);
            mess_link.appendChild(mess_img);
            if (settings_message_icon_new_win) mess_link.setAttribute("target", "_blank");
            mess_link.setAttribute("href", "/account/messagecenter?recipientId=" + guid + "&text=" + template_message);
            b_side.parentNode.insertBefore(mess_link, b_side.nextSibling);
            b_side.parentNode.insertBefore(document.createTextNode(" "), b_side.nextSibling);
            // "Message this owner" und Icon entfernen.
            $('#ctl00_ContentBody_mcd1').find(".message__owner").remove();  // Cache Listing
            $('.BugDetailsList').find(".message__owner").remove();  // TB Listing
        }
        // Mail Icon erzeugen.
        if (settings_show_mail) {
            var mail_link = document.createElement("a");
            var mail_img = document.createElement("img");
            mail_img.setAttribute("style", "margin-left: 0px; margin-right: 0px");
            mail_img.setAttribute("title", "Send a mail to " + username_send);
            mail_img.setAttribute("src", global_mail_icon);
            mail_link.appendChild(mail_img);
            if (settings_mail_icon_new_win) mail_link.setAttribute("target", "_blank");
            if (b_art == "per guid") {
                mail_link.setAttribute("href", "/email/?guid=" + guid + "&text=" + template);
                b_side.parentNode.insertBefore(mail_link, b_side.nextSibling);
                b_side.parentNode.insertBefore(document.createTextNode(" "), b_side.nextSibling);
            } else {
                b_side.appendChild(document.createTextNode(" "));
                mail_link.setAttribute("href", "/email/?u=" + urlencode(b_username, convertPlus = false) + "&text=" + template);
                b_side.appendChild(mail_link);
                b_side.appendChild(document.createTextNode(" "));
            }
        }
    }

    function appendCssStyle(css, name) {
            if (css == "") return;
            if (name) var tag = $(name)[0];
            else var tag = $('head')[0];
            var style = document.createElement('style');
            style.innerHTML = 'GClhII{} ' + css;
            style.type = 'text/css';
            tag.appendChild(style);
    }
    function showMyLog(glnk){
            $.ajax({
            type: "GET",
            url: glnk,
            contentType: "html; charset=utf-8",
            error: function (XMLHttpRequest, textStatus, errorThrown) {
            console.log("Improve Watch button handling.", 'AJAX call failed')
            },
            success: function (aaa){console.log("success");
//            var a = '<center>'+'<a href="'+glnk+'">Show My log on new window</a>&nbsp;&nbsp;<b>'+$(aaa).find('#ctl00_ContentBody_LogBookPanel1_LogDate')[0].innerHTML+'</b></center><hr>';
			var a=$(aaa).find('#__next > div > div.page-container > div > div > div.log-view-page-content > div.css-o17ywg > div.log-view-body > div.log').innerHTML;
            a+=$(aaa).find('#ctl00_ContentBody_LogBookPanel1_LogText')[0].innerHTML;;
//                              document.getElementById("MyLog").innerHTML=a.replace(/..\/images\/icons\/icon_smile.gif/g,'https://mozilive.zubor.net/ikonky/icon_smile.gif'));
            document.getElementById("MyLog").innerHTML=a.replace(/icon_smile.gif/g,'icon_smile.png');
            }
            });
    }
    function cachePopupOnBrowseMap() {
        try {
//			alert($("#cacheDetailsTemplate").html);
            var template = $("#cacheDetailsTemplate").html().trim().replace(' class="lnk send2gps"',' class="lnk send2gps" target="_blank"');
			// {{=gc}} will be replaced by the GC-Code, so the div is unique
            var new_template = '';
                new_template += '<div id="popup_additional_info_{{=gc}}" class="links Clear popup_additional_info">';
                new_template += '    <div class="loading_container">';
                new_template += '        <img src="data:image/gif;base64,R0lGODlhEAALAPQAAP///wAAANra2tDQ0Orq6gYGBgAAAC4uLoKCgmBgYLq6uiIiIkpKSoqKimRkZL6+viYmJgQEBE5OTubm5tjY2PT09Dg4ONzc3PLy8ra2tqCgoMrKyu7u7gAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCwAAACwAAAAAEAALAAAFLSAgjmRpnqSgCuLKAq5AEIM4zDVw03ve27ifDgfkEYe04kDIDC5zrtYKRa2WQgAh+QQJCwAAACwAAAAAEAALAAAFJGBhGAVgnqhpHIeRvsDawqns0qeN5+y967tYLyicBYE7EYkYAgAh+QQJCwAAACwAAAAAEAALAAAFNiAgjothLOOIJAkiGgxjpGKiKMkbz7SN6zIawJcDwIK9W/HISxGBzdHTuBNOmcJVCyoUlk7CEAAh+QQJCwAAACwAAAAAEAALAAAFNSAgjqQIRRFUAo3jNGIkSdHqPI8Tz3V55zuaDacDyIQ+YrBH+hWPzJFzOQQaeavWi7oqnVIhACH5BAkLAAAALAAAAAAQAAsAAAUyICCOZGme1rJY5kRRk7hI0mJSVUXJtF3iOl7tltsBZsNfUegjAY3I5sgFY55KqdX1GgIAIfkECQsAAAAsAAAAABAACwAABTcgII5kaZ4kcV2EqLJipmnZhWGXaOOitm2aXQ4g7P2Ct2ER4AMul00kj5g0Al8tADY2y6C+4FIIACH5BAkLAAAALAAAAAAQAAsAAAUvICCOZGme5ERRk6iy7qpyHCVStA3gNa/7txxwlwv2isSacYUc+l4tADQGQ1mvpBAAIfkECQsAAAAsAAAAABAACwAABS8gII5kaZ7kRFGTqLLuqnIcJVK0DeA1r/u3HHCXC/aKxJpxhRz6Xi0ANAZDWa+kEAA7AAAAAAAAAAAA" /> Loading additional Data ...';
                new_template += '    </div>';
                new_template += '</div>';

            var pos = template.lastIndexOf('</div>');
//			alert(pos);
//			alert('template='+template.indexOf(new_template));
            //Ochrana proti viacnasobnemu zavolaniu a duplikovanemu zobrazeniu logov
			if (template.indexOf(new_template)==-1)
			{template = template.substring(0,pos) + new_template + '</div>';
			$("#cacheDetailsTemplate").html(template);
			}
//			alert(template);
            // Select the target node.
            var target = document.querySelector('.leaflet-popup-pane');
            var settings_show_enhanced_map_coords=true;
            var settings_show_latest_logs_symbols_count_map=15;
            var settings_show_country_in_place=false;
            var settings_show_elevation_of_waypoints=true;
            var settings_process_vup=false;
            var browser='IE10';
            if (settings_show_enhanced_map_coords) var css = "div.popup_additional_info {min-height: 82px;}";
            else var css = "div.popup_additional_info {min-height: 64px;}";
            css += "div.popup_additional_info .loading_container{display: flex; justify-content: center; align-items: center;}"
            css += "div.popup_additional_info .loading_container img{margin-right:5px;}"
            css += "div.popup_additional_info span.favi_points svg, div.popup_additional_info span.tackables svg{position: relative;top: 4px;}";
            css += "div.popup_additional_info li {display: inline;}"
            css += ".leaflet-popup-content-wrapper, .leaflet-popup-close-button {margin: 16px 3px 0px 13px;}";
            css += ".gclh_ctoc img {width: 14px; padding: 3px 1px 0 0; float: right;}";
            css += "div.gclh_latest_log, span.gclh_cache_note {margin-top:5px;}";
            css += "div.gclh_latest_log:hover, span.gclh_cache_note:hover {position: relative;}";
            css += "div.gclh_latest_log span, span.gclh_cache_note span {display: none; position: absolute; left: 0px; width: 500px; padding: 5px; text-decoration:none; text-align:left; vertical-align:top; color: #000000; word-break: break-word;}";
            css += "div.gclh_latest_log:hover span, span.gclh_cache_note:hover span {font-size: 13px; display: block; top: 16px; border: 1px solid #8c9e65; background-color:#dfe1d2; z-index:10000;}";
            css += "span.premium_only img {margin-right:0px;}";
            css += "#ownBMLsCount {cursor: default;} .map-item .send2gps img {margin-right: 0px;}";
            css += ".LogTotals, .LogTotals li {display: inline-block; margin: 0;} .LogTotals li {margin-right: 5px;}";
			css += ".highlight-cross { width: 12px; height: 12px; background: red; border-radius: 50%; border: 2px solid white; box-shadow: 0 0 5px black; z-index: 10000; pointer-events: none; transform: translate(-50%, -50%);}";
			if (browser == 'firefox') css += ".gclh_owner {max-width: 110px;} .map-item h4 a {max-width: 265px;} .gclh_owner, .map-item h4 a {display: inline-block; white-space: nowrap; overflow: -moz-hidden-unscrollable; text-overflow: ellipsis;}";
            appendCssStyle(css);

            // Create an observer instance.
            var observer = new MutationObserver(function(mutations) {
                mutations.forEach(function(mutation) {
                    gccode = $('#gmCacheInfo .code').html();
                    if (gccode == null) return;
                    // Listing coordinates of all caches in additional popup.
                    var locations = [];
                    // Count of caches (map-items) in additional popup.
                    var countMapItems = $('.map-item').length;
                    // New Popup. This can contain more than one cache (if 2 or more are close together)
                    // so we have to load informations for all caches.
                    $('#gmCacheInfo .map-item').each(function () {
                        gccode = $(this).find('.code').html();

                        if ($('#already_loading_' + gccode)[0]) return;
                        $(this).find('dl dt')[0].innerHTML = "";
                        if (browser == 'firefox') {
                            $(this).find('h4 a')[0].title = $(this).find('h4 a')[0].innerHTML.replace(/<strike>/,'').replace(/<\/strike>/,'');
                            $(this).find('dl dd')[0].childNodes[0].innerHTML = '<span class="gclh_owner" title="' + $(this).find('dl dd')[0].childNodes[0].innerHTML + '">' + $(this).find('dl dd')[0].childNodes[0].innerHTML + '</span>';
                        }

                        // Add hidden Div, so we can know, that we are already loading data.
                        $(this).find('#popup_additional_info_' + gccode).append('<div id="already_loading_' + gccode +'"></div>');

                        // Get index of map items.
                        var indexMapItems = 1;//$(this).find('#popup_additional_info_' + gccode).closest('.map-item')[0].className.match(/map-item-row-(\d+)/);
                        var indexMapItems = indexMapItems[1] -1;

                        $.get('https://www.geocaching.com/geocache/'+gccode, null, function(text){
                            // We need to retriev the gc_code from the loaded page, because in the
                            // meantime the global variable gc_code could (and will be ;-)) changed.
                            var local_gc_code = $(text).find('#ctl00_ContentBody_CoordInfoLinkControl1_uxCoordInfoCode').html();

                            var premium_only = false;
                            if ($(text).find('p.Warning.NoBottomSpacing').html() != null) {
                                premium_only = true;
                            }

                            // Get the last logs.
                            var initalLogs_from_cachepage = text.substr(text.indexOf('initialLogs = {"status')+13, text.indexOf('} };') - text.indexOf('initialLogs = {"status') - 10);
                            var initalLogs = JSON.parse(initalLogs_from_cachepage);
                            var last_logs = document.createElement("div");
                            var last_logs_to_show = settings_show_latest_logs_symbols_count_map;
                            var lateLogs = new Array();
                            for (var i = 0; i < initalLogs['data'].length; i++) {
                                if (last_logs_to_show == i) break;
                                var lateLog = new Object();
                                lateLog['user'] = initalLogs['data'][i].UserName;
                                lateLog['src']  = '/images/logtypes/' + initalLogs['data'][i].LogTypeImage;
                                lateLog['type'] = initalLogs['data'][i].LogType;
                                lateLog['date'] = initalLogs['data'][i].Visited;
                                lateLog['log']  = initalLogs['data'][i].LogText;
                                lateLogs[i]     = lateLog;
                            }
                            if (lateLogs.length > 0) {
                                var div = document.createElement("div");
                                div.id = "gclh_latest_logs";
                                div.setAttribute("style", "padding-right: 0; display: flex;");
                                var span = document.createElement("span");
                                span.setAttribute("style", "white-space: nowrap; margin-right: 5px; margin-top: 5px;");
                                span.appendChild(document.createTextNode('Latest logs:'));
                                div.appendChild(span);
                                var inner_div = document.createElement("div");
                                inner_div.setAttribute("style", "display: flex; flex-wrap: wrap;");
                                div.appendChild(inner_div);
                                for (var i = 0; i < lateLogs.length; i++) {
                                    var div_log_wrapper = document.createElement("div");
                                    div_log_wrapper.className = "gclh_latest_log";
                                    var img = document.createElement("img");
                                    img.src = lateLogs[i]['src'];
                                    img.setAttribute("style", "padding-left: 2px; vertical-align: bottom; float:left;");
                                    var log_text = document.createElement("span");
                                    log_text.title = "";
                                    log_text.innerHTML = "<img src='" + lateLogs[i]['src'] + "'> <b>" + lateLogs[i]['user'] + " - " + lateLogs[i]['date'] + "</b><br>" + lateLogs[i]['log'];
                                    div_log_wrapper.appendChild(img);
                                    div_log_wrapper.appendChild(log_text);
                                    inner_div.appendChild(div_log_wrapper);
                                }
                                last_logs.appendChild(div);
                            }

                            // Get all type of logs and their count.
//                            var all_logs = $(text).find('.LogTotals')[0].innerHTML.replace(/alt="(.*?)"/g, "alt=\"...\"");
                            if ($(text).find('#ctl00_ContentBody_lblFindCounts')[0]) {
                                var all_logs = $(text).find('#ctl00_ContentBody_lblFindCounts')[0].innerHTML.replace(/alt="(.*?)"/g, "alt=\"...\"").replace(/&nbsp;/g, " ");
                            } else var all_logs = '';
//							alert(all_logs);
                            // Get the number of trackables in the cache.
                            var trachables = 0;
                            $(text).find('.CacheDetailNavigationWidget').each(function(){
                                tb_text = $(this).html();
                                if (tb_text.indexOf('ctl00_ContentBody_uxTravelBugList_uxInventoryLabel') !== -1) {
                                    // There are two Container with .CacheDetailNavigationWidget so we are only processing the
                                    // one that contains the TB informations.
                                    trachables = (tb_text.match(/<li>/g)||[]).length;
                                }
                            });

                            // Get the number of favorite points.
                            var fav_points = $(text).find('.favorite-value').html();
                            if (fav_points == null) {
                                // Couldn't get Number of Favorits. This happens with event caches for example.
                                fav_points = 0;
                            } else {
                                fav_points = fav_points.replace('.','');
                                fav_points = fav_points.replace(',','');
                                fav_points = parseInt(fav_points);
                            }

                            // Set dummy favorite score.
                            var fav_percent = ' ';

                            // Get the place, where the cache was placed.
                            if ($(text).find('#ctl00_ContentBody_Location a')[0]) var place = $(text).find('#ctl00_ContentBody_Location a')[0].innerHTML;
                            else var place = $(text).find('#ctl00_ContentBody_Location')[0].innerHTML.replace(/(.*?)\s/,'');

                            // Put all together.
//                            var new_text = '<span style="margin-right: 5px;">Logs:</span>' + all_logs.replace(/&nbsp;/g, " ") + '<br>';
							var new_text = '<span style="margin-right: 5px;">Logs:</span>' + all_logs.replace(/&nbsp;/g, " ")+'';
                            new_text += $(last_logs).prop('outerHTML');
                            new_text += '<div style="padding-bottom: 3px;">';
                            if (settings_show_country_in_place) new_text += '<span title="Place">' + place + '</span> | ';
                            else new_text += '<span title="' + place + '">' + place.replace(/(,.*)/,'') + '</span> | ';
                            if (settings_show_elevation_of_waypoints) {
                                new_text += '<span id="elevation-waypoint-'+indexMapItems+'"></span>';
                            }
                            new_text += '<span class="favi_points" title="Favorites in percent"><svg height="16.5" width="16.5"><image xmlns:xlink="https://www.w3.org/1999/xlink" xlink:href="/images/icons/fave_fill_16.svg" src="/images/icons/fave_fill_16.png" width="16" height="16" alt="Favorite points"></image></svg> ' + fav_percent + '</span> | ';
                            if (premium_only) {
                                new_text += ' <span class="premium_only" title="Premium Only Cache"><img src="/images/icons/16/premium_only.png" width="16" height="16" alt="Premium Only Cache" /></span> | ';
                            }
                            new_text += '<span class="trackables" title="Number of trackables"><svg height="16" width="16" class="icon-sm"><use xmlns:xlink="https://www.w3.org/1999/xlink" xlink:href="/account/app/ui-icons/sprites/global.svg#icon-travelbug-default"></use></svg> ' + trachables + '</span>';

                            // Get link to image gallery and image count.
                            var a = $(text).find('.CacheDetailNavigation ul li').find('a[href*="/seek/gallery.aspx?guid="]');
                            if (a) {
                                var galleryLink = a[0].href;
                                var imgCount = a[0].innerHTML.match(/(\s*)\((\d+)\)/);
                                if (galleryLink && imgCount && imgCount[2]) {
                                    if (imgCount[2] == "0") new_text += ' | <span title="No Image Gallery"><a style="color: #939597; text-decoration: none;">';
                                    else new_text += ' | <span title="View Image Gallery"><a href="' + galleryLink + '">';
                                    new_text += '<img src="/images/icons/16/photo_gallery.png" style="height: 14px; vertical-align: text-bottom;">' + imgCount[2] + '</a></span>';
                                }
                            }

                            // Get personal cache note.
                            if ($(text).find('#srOnlyCacheNote')[0]) {
                                if (!$(text).find('#srOnlyCacheNote')[0].innerHTML || $(text).find('#srOnlyCacheNote')[0].innerHTML == '') {
                                    new_text += ' | <span title="No personal cache note"><svg style="opacity: 0.5; vertical-align: middle;" height="16" width="16"><use xlink:href="#messages--inline"></use></svg></span>';
                                } else {
                                    new_text += ' | <span class="gclh_cache_note"><svg style="color: #4a4a4ad4; vertical-align: middle;" height="16" width="16"><use xlink:href="#messages--inline"></use></svg><span style="left: -250px; width: 300px;">' + $(text).find('#srOnlyCacheNote').html().replace(/\n/gi,'<br>') + '</span></span>';
                                }
                            }
                            var a = $(text).find('#ctl00_ContentBody_GeoNav_logDate').find('a[href*="/seek/log.aspx?LUID="]');
                            
                            if (a.length>0) {          
                            var glnk = a[0].href;    
//							alert(txt2);
                            new_text += '<hr><span id="MyLog" class="gclh_latest_log" title="MyLog"><a href="'+glnk+'">Click here for show MyLog</a></span>';                            
//                            showMyLog(glnk);  
//                            $("#MyLog").click(function() {showMyLog(galleryLink);});
//                            $(document).on("click", "#MyLog" , function() {showMyLog(glnk);});
                            }
                        	    
                            new_text += '</div>';

                            // Get coordinates.
                            var coords = $(text).find('#uxLatLon')[0].innerHTML;
                            var original_coords = "";
                            var original_coords_span = "";
                            var corrected = "";
                            if (text.match(/"isUserDefined":true/gm)) {
                                var original_coords = text.match(/oldLatLngDisplay":"(N|S).*(E|W).*?'"/gm);
                                original_coords = String(original_coords[0]);
                                original_coords = original_coords.replace("oldLatLngDisplay\":\"","");
                                original_coords = original_coords.replace("\"","");
                                original_coords = original_coords.replace(new RegExp('\'', 'g'),'');
                                original_coords_span = ' <span class="coordinates original" title="original Coordinates">&nbsp;( <span class="anker"></span>' + original_coords + ' )</span>';
                                corrected = "corrected ";
                            }
                            if (settings_show_enhanced_map_coords) {
                                new_text += '<span><span class="coordinates current" title="'+corrected+'Coordinates">' + coords + '</span>' + original_coords_span + '</span>';
                            }

                            $('#popup_additional_info_' + local_gc_code).html(new_text);

                            // Get count and names of own bookmarklists.
                            if ($('#popup_additional_info_' + local_gc_code).closest('.map-item')[0]) {
                                var item = $('#popup_additional_info_' + local_gc_code).closest('.map-item')[0];
                                if ( !$(item).find('#ownBMLsCount')[0] && $(item).find('.btn-add-to-list > span')[0] ) {
//                                    var [ownBMLsCount, ownBMLsText, ownBMLsList] = getOwnBMLs(text);
                                    var pp = getOwnBMLs(text);var ownBMLsCount=pp[0];var ownBMLsText=pp[1];var ownBMLsList=pp[2];                                    
//                                    $(item).find('.btn-add-to-list')[0].after($('<span id="ownBMLsCount"> (' + ownBMLsCount + ')</span>')[0]);
//									console.log('text='+text);
//                                    console.log('pp='+pp);
									var pa=$(item).find('.btn-add-to-list')[0];
									var pb=$('<span id="ownBMLsCount"> (' + ownBMLsCount + ')</span>')[0];
									pa.parentNode.insertBefore(pb,pa.nextSibling);
									console.log('pa='+pa);
									
//                                      $(item).find('.btn-add-to-list')[0].parentNode.insertBefore($('<span id="ownBMLsCount"> (' + ownBMLsCount + ')</span>')[0],$(item).find('.btn-add-to-list')[0].nextSibling);
//                                    $(ddl1).after(typeErrordiv);
//                                    ddl1.parentNode.insertBefore(typeErrordiv, ddl1.nextSibling);
                                    
                                    $(item).find('.btn-add-to-list > span')[0].setAttribute('title', ownBMLsText);
                                    $(item).find('#ownBMLsCount')[0].setAttribute('title', ownBMLsList);
                                }
                            }

                            // Add Copy to Clipboard Links.
                            if (settings_show_enhanced_map_coords) {
                                if (original_coords != "") {
                                    addCopyToClipboardLink(original_coords, $('#popup_additional_info_' + local_gc_code + ' span.coordinates.original .anker')[0], "original Coordinates", 'vertical-align: bottom; margin-right: -6px;');
                                }
                                addCopyToClipboardLink(coords, $('#popup_additional_info_' + local_gc_code + ' span.coordinates.current')[0], corrected+"Coordinates", 'vertical-align: bottom; margin-right: -6px;');
                            }

                            // Get favorite score.
                            var from = text.indexOf('userToken', text.indexOf('MapTilesEnvironment')) + 13;
                            var length = text.indexOf("';", from) - from;
                            var userToken = text.substr(from, length);
//                            getFavoriteScore(local_gc_code, userToken);

							getFavoriteScore(local_gc_code, function(score) {
                                var id = '#popup_additional_info_' + local_gc_code + ' .favi_points';
                                if ($(id)[0] && $(id)[0].childNodes[1]) $(id)[0].childNodes[1].data = " "+score+"%";
                            });

                            // Get elevations.
                            if (settings_show_elevation_of_waypoints) {
                                var coords = toDec($(text).find('#uxLatLon')[0].innerHTML);
                                locations.push(coords[0]+","+coords[1]);
                                if (locations && locations.length == countMapItems) getElevations(0,locations);
                            }
/*				
				// Show Weekday for Events.
                            if (settings_show_eventday && text.match(/eventCacheData/)) {
                                var matchDate = text.match(/new Date\((\d{4}), (\d{2})-1, (\d{2})/);
                                if (matchDate != null) {
                                    var date = new Date(matchDate[1], matchDate[2]-1, matchDate[3]);
                                    if (date != "Invalid Date") {
                                        $('#gclh_weekday_'+local_gc_code).html(` (${date.getWeekday(short = true)})`);
                                    }
                                }
                            }
*/							
						if (settings_show_eventday && text.match(/eventCacheData/)) {
						var matchDate = text.match(/new Date\((\d{4}), (\d{2})-1, (\d{2})/);
						if (matchDate !== null) {
						var year = parseInt(matchDate[1], 10);
						var month = parseInt(matchDate[2], 10) - 1; // Měsíc v Date začíná od 0
						var day = parseInt(matchDate[3], 10);
						var date = new Date(year, month, day);
						if (!isNaN(date.getTime())) { // Ověření, zda je datum platné
						// Přidání funkce pro získání názvu dne v týdnu
						if (!Date.prototype.getWeekday) {
						Date.prototype.getWeekday = function (short) {
						var weekdays = short
                        ? ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']
                        : ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
						return weekdays[this.getDay()];
						};
						}

						var weekdayShort = date.getWeekday(true); // Získání zkráceného názvu dne
						document.getElementById('gclh_weekday_' + local_gc_code).innerHTML = ' (' + weekdayShort + ')';
							}
						}
						}
							

                        });

                        // Improve Original Box Content.
                        side = $(this).find('dl dd a');
                        guid = side.attr('href').substring(15,36+15);
                        username = side.text();
                        buildSendIcons(side[0], username, "per guid", guid);
                        var link = gclh_build_vipvup(username, global_vips, "vip");
                        link.children[0].style.marginLeft = "5px";
                        link.children[0].style.marginRight = "3px";
                        side[0].appendChild(link);
                        // Build VUP Icon.
                        if (settings_process_vup && username != global_activ_username) {
                            link = gclh_build_vipvup(username, global_vups, "vup");
                            link.children[0].setAttribute("style", "margin-left: 0px; margin-right: 0px");
                            side[0].appendChild(link);
                        }
                        addCopyToClipboardLink(gccode, $(this).find('h4')[0], "GC Code", "float: right;");
                    });
                });
            });

            // Configuration of the observer.
            var config = { attributes: true, childList: true, characterData: true };
            // Pass in the target node, as well as the observer options.
            observer.observe(target, config);
        } catch(e) {console.log("enhance cache popup",e);}
    }
cachePopupOnBrowseMap();
})();
//=============================================================================================================================
// ==UserScript==
// @name        Geocaching Map Enhancements - add support for mozilive
// @version     0.8.2 + modification for mozilive
// @author      JRI
// @oujs:author JRI
// @namespace   inge.org.uk/userscripts
// @description Adds extra maps and grid reference search to Geocaching.com, along with several other enhancements.
// @include     https://www.geocaching.com/*
// @license     MIT; http://www.opensource.org/licenses/mit-license.php
// @copyright   2011-18, James Inge (http://geo.inge.org.uk/)
// @attribution GeoNames (http://www.geonames.org/)
// @attribution Postcodes.io (https://postcodes.io/)
// @attribution Chris Veness (http://www.movable-type.co.uk/scripts/latlong-gridref.html)
// @grant       GM_xmlhttpRequest
// @grant       GM.xmlHttpRequest
// @connect     geograph.org.uk
// @connect     channel-islands.geographs.org
// @connect     geo-en.hlipp.de
// @connect     api.geonames.org
// @connect     api.postcodes.io
// @connect     www.geocaching.com
// @connect     api.open-elevation.com
// @icon        https://geo.inge.org.uk/userscripts/GeocachingMap48.png
// @icon64      https://geo.inge.org.uk/userscripts/GeocachingMap64.png
// @updateURL   https://geo.inge.org.uk/userscripts/GeocachingMapEnhancements.meta.js
// @downloadURL https://openuserjs.org/install/JRI/Geocaching_Map_Enhancements.user.js
// ==/UserScript==

/* jshint multistr: true */
/* global $, amplify, DMM, FileReader, GM, GM_xmlhttpRequest, Groundspeak, L, LatLon, mapLatLng, MapSettings */
window.currentFilename = "";
(function () {
"use strict";

var gmeResources = {
	parameters: JSON.parse(localStorage.getItem("GME_parameters"))	
/*parameters: {
			// Defaults
			version: "0.9.0 +mozigo",
			versionMsg: "Icons fix, API key, Default hill shader",
			brightness: 1,	// Default brightness for maps (0-1), can be overridden by custom map parameters.
			filterFinds: false, // True filters finds out of list searches.
			follow: false,	// Locator widget follows current location (moving map mode)
			labels: "codes", // Label caches on the map with their GC code. Or "names" to use long name.
			measure: "metric",	// Or "imperial" - used for the scale indicators
			osgbSearch: true,	// Enhance search box with OSGB grid references, zooming, etc. (may interfere with postal code searches)
			defaultMap: "OpenStreetMap",
			defaultHillShading: "Hillshading",
			maps: [
				//	{alt:"Readable Name", tileUrl: "URL template including {s} (subdomain) and either {q} (quadkey) or {x},{y},{z} (Google/TMS tile coordinates + zoom)", subdomains: "0123", minZoom: 0, maxZoom: 24, attribution: "Copyright message (HTML allowed)", name: "shortname", overlay:false }
				{ alt: "OpenStreetMap", tileUrl: "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", name: "osm", subdomains: "abc" },
				{ alt: "Bing Maps", tileUrl: "https://ecn.t{s}.tiles.virtualearth.net/tiles/r{q}?g=864&mkt=en-gb&lbl=l1&stl=h&shading=hill&n=z", subdomains: "0123", minZoom: 1, maxZoom: 20, attribution: "<a href=\'https://www.bing.com/maps/\'>Bing</a> map data copyright Microsoft and its suppliers", name: "bingmap", ignore: true },
				{ alt: "Bing Aerial View", tileUrl: "https://ecn.t{s}.tiles.virtualearth.net/tiles/a{q}?g=737&n=z", subdomains: "0123", minZoom: 1, maxZoom: 20, attribution: "<a href=\'https://www.bing.com/maps/\'>Bing</a> map data copyright Microsoft and its suppliers", name: "bingaerial" },
				{ alt: "Google Maps", tileUrl: "https://mt.google.com/vt?&x={x}&y={y}&z={z}", name: "googlemaps", attribution: "<a href=\'https://maps.google.com/\'>Google</a> Maps", subdomains: "1234", tileSize: 256, maxZoom: 22 },
				{ alt: "Google Satellite", tileUrl: "https://mt.google.com/vt?lyrs=s&x={x}&y={y}&z={z}", name: "googlemapssat", attribution: "<a href=\'https://maps.google.com/\'>Google</a> Maps Satellite", subdomains: "1234", tileSize: 256, maxZoom: 22 },
				{ alt: "Freemap Slovakia Hiking", tileUrl: "http://t{s}.freemap.sk/T/{z}/{x}/{y}.jpeg", attribution: "Map &copy; <a href='http://www.freemap.sk/'>Freemap Slovakia</a>, data &copy; <a href='http://openstreetmap.org'>OpenStreetMap</a> contributors", subdomains: "1234", minZoom: 8, maxZoom: 16, ignore: true },
				{ alt: "Freemap Slovakia Bicycle", tileUrl: "http://t{s}.freemap.sk/C/{z}/{x}/{y}.jpeg", attribution: "Map &copy; <a href='http://www.freemap.sk/'>Freemap Slovakia</a>, data &copy; <a href='http://openstreetmap.org'>OpenStreetMap</a> contributors", subdomains: "1234", minZoom: 8, maxZoom: 16, ignore: true },
				{ alt: "Freemap Slovakia Car", tileUrl: "http://t{s}.freemap.sk/A/{z}/{x}/{y}.jpeg", attribution: "Map &copy; <a href='http://www.freemap.sk/'>Freemap Slovakia</a>, data &copy; <a href='http://openstreetmap.org'>OpenStreetMap</a> contributors", subdomains: "1234", minZoom: 8, maxZoom: 16, ignore: true },
				{ alt: "Mapy.cz - Turistická", tileUrl: "https://m{s}.mapserver.mapy.cz/turist-m/{z}-{x}-{y}", minZoom: 5, maxZoom: 18, subdomains: "1234", attribution: "© <a href='//www.seznam.cz' target='_blank'>Seznam.cz, a.s.</a>, © <a href='http://www.openstreetmap.org/copyright'>OpenStreetMap</a>, © NASA" },
				{ alt: "Hillshading", tileUrl: "http://{s}.tiles.wmflabs.org/hillshading/{z}/{x}/{y}.png", subdomains: "abc", attribution: "Hillshading by <a	 href=\'https://wiki.openstreetmap.org/wiki/Hike_%26_Bike_Map\'>Colin Marquardt</a> from NASA SRTM data", overlay: true }
			],
			apiKeys: {},
	}*/,
	css: {
		main: '.leaflet-control-gme,.leaflet-control-zoomwarning {border-radius:7px; filter: progid:DXImageTransform.Microsoft.gradient(startColorStr="#3F000000",EndColorStr="#3F000000"); padding:5px;z-index:8;}\
			.leaflet-control-gme {display: inline-block; padding: 0; background: rgba(0, 0, 0, 0.2); box-shadow: 0 0 8px rgba(0, 0, 0, 0.4);}\
			.gme-control-scale {bottom:5em !important;margin-left:13px !important; left: 385px;}\
			.gme-left {left: 385px; margin-left:13px !important;}\
			div.gme-identify-layer {margin-top:-1em;margin-left:1em;padding-left:0.1em;font-weight:bold;background:rgba(255,255,255,0.57);}\
			#gme_caches table { margin-top: 0.5em; }\
			.GME_search_list { border: 1px solid #679300; border-radius: 7px; padding: 0.5em; }\
			div.GME_search_results { margin-right: -65px; }\
			.GME_search_results.hidden { display: none; }\
			.groundspeak-control-findmylocation { border: 1px solid #888; border-radius: 5px; box-shadow: 0 0 8px rgba(0, 0, 0, 0.4); padding:0; background:rgba(255,255,255,0.8);}\
			.groundspeak-control-findmylocation a { padding: 3px; }\
			.gme-button { display: inline-block; box-sizing: content-box; -moz-box-sizing: content-box; padding:3px; vertical-align:middle; background:url(https://raw.githubusercontent.com/ionic-team/graphite/master/docs/themes/aloe/images/icons-18-black.png) no-repeat #eee; background-color: rgba(255,255,255,0.8); border: 1px solid #888; border-right:0; height:19px; width:19px; text-decoration: none; }\
			.gme-button-l { border-bottom-left-radius:5px; border-top-left-radius:5px; }\
			.gme-button-r { border-right: 1px solid #888; border-bottom-right-radius: 5px; border-top-right-radius:5px; margin-right:0.5em;}\
			.gme-button:hover { background-color: #fff; }\
			.gme-button-active {border:solid 3px #02b; padding:1px 0 1px 1px; background-color:#fff;}\
			.gme-button-active:hover {border-color:#63f;filter:alpha(opacity=100);}\
			span.gme-button, .gme-button-wide { padding-left:5px; padding-right:5px; font-size:12px; font-weight:bold; width:auto; background-image:none; color: #424242; }\
			.GME_home { background-position: -572px 4px;}\
			.GME_config { background-position: -284px 4px;}\
			.GME_route, .GME_hide, .GME_wpthide {background: url(https://geo.inge.org.uk/userscripts/gme_icons_0_8_0.png) no-repeat #eee;}\
			.GME_route { background-position: 7px 3px;}\
			.GME_route.gme-button-active { background-position: 5px 1px;}\
			.GME_hide { background-position: -17px 3px;}\
			.GME_hide.gme-button-active { background-position: -19px 1px;}\
			.GME_wpthide { background-position: -17px 3px;}\
			.GME_wpthide.gme-button-active { background-position: -19px 1px;}\
			.gme-button-refresh-labels { background-position: -320px 4px;}\
			.gme-button-clear-labels { background-position: -69px 4px;}\
			span.gme-distance-container { display: none; }\
			span.gme-distance-container.show { display: inline-block; }\
			.GME_info { background-position: -537px 4px;}\
			.GME_info.gme-button-active {background-position: -540px 1px;}\
			#GME_loc, a.gme-button.leaflet-active {outline: none;}\
			.leaflet-control-zoomwarning { top: 94px; }\
			.leaflet-control-zoomwarning a { filter: progid:DXImageTransform.Microsoft.gradient(startColorStr="#BFC80000",EndColorStr="#BFC80000"); background-color:rgba(200,0,0,0.75); margin-left: -4px; background-position: -502px 2px;height:14px;width:14px; border-color: #b00; box-shadow: 0 0 8px rgba(0, 0, 0, 0.4); }\
			.leaflet-control-zoomwarning a:hover { background-color:rgba(230,0,0,0.75); }\
			.gme-event { cursor: pointer; }\
			.gme-modalDialog {position: fixed; top: 0; right: 0; bottom: 0; left: 0; background: rgba(0,0,0,0.5); z-index: 1000; opacity:.5; -webkit-transition: opacity 400ms ease-in; -moz-transition: opacity 400ms ease-in; transition: opacity 400ms ease-in; pointer-events: none; display:none; }\
			.gme-modalDialog:target, .gme-modalDialog.gme-targetted { opacity:1; display:block; pointer-events: auto; }\
			.gme-modalDialog > div { position: relative; margin: 4% 12.5%; height: 30em; max-height: 75%; padding: 0 0 13px 0; border: 1px solid #000; border-radius: 10px; background: #fff; background: -moz-linear-gradient(#fff, #999); background: -webkit-linear-gradient(#fff, #999); background: -o-linear-gradient(#fff, #999); }\
			.gme-modalDialog header { color: #eee; background: none #454545; font-size: 15px; text-align: center; border-top-left-radius: 10px; padding: 0.5em 0; font-weight: bold; text-shadow: none; height: auto; min-height: auto; min-width: auto; }\
			.gme-modal-content { position: absolute; top: 3.5em; left: 0.75em; right: 0.75em; bottom: 0.5em; overflow: auto; }\
			.gme-modal-content > .leaflet-control-gme { position: absolute; left: 0.5em; bottom: 0.5em; top: auto; }\
			.gme-close-dialog { background: #606061; color: #fff; line-height: 25px; position: absolute; right: -12px; text-align: center; top: -10px; width: 24px; text-decoration: none; font-weight: bold; -webkit-border-radius: 12px; -moz-border-radius: 12px; border-radius: 12px; -moz-box-shadow: 1px 1px 3px #000; -webkit-box-shadow: 1px 1px 3px #000; box-shadow: 1px 1px 3px #000; }\
			.gme-close-dialog:hover { background: #00d9ff; }\
			#searchtabs li a { padding: 1em 0.5em; }\
			@media print { #search { display: none !important}}\
			.tab-switcher { position: relative; font-family: Arial, sans-serif; font-size: 14px; }\
			.gme-tab { float: left; }\
			.gme-tab-label { border-radius: 8px 8px 0 0; border: 1px solid #ccc; color: #454545; background: #ddd; display: block; position: relative; margin-left: 15px; padding: 3px 0; font-weight: bold; z-index: 0; }\
			.gme-tab-label:after { border-bottom: 1px solid #ccc; border-bottom-left-radius: 8px; border-left: 1px solid #ccc; box-shadow: -2px 2px 0 #ddd; bottom: -8px; content: ""; display: inline-block; height: 8px; left: 9px; position: relative; width: 8px; z-index: 3;}\
			.gme-tab-label:before { border-bottom: 1px solid #ccc; border-bottom-right-radius: 8px; border-right: 1px solid #ccc; box-shadow: 2px 2px 0 #ddd; bottom: -8px; content: ""; display: inline-block; height: 8px; left: -9px; position: relative; width: 8px; z-index: 3; }\
			.gme-tab-label:hover { cursor: pointer; }\
			.gme-tab-content { position: absolute; top: 25px; bottom: 3.5em; left: 0; right: 0; padding: 0.5em; background: #000; border: 1px solid #ccc; border-radius: 8px; color: #555; z-index: 1; opacity: 0; overflow: auto; }\
			.gme-tab-content ul { margin: 0.5em 0; }\
			.gme-tab input[type=radio] { display: none; }\
			.gme-tab input[type=radio]:checked ~ .gme-tab-content { z-index: 2; opacity: 1; background: #fff; color: #454545; }\
			.gme-tab input[type=radio]:checked ~ .gme-tab-label { background: #fff; color: #454545; border-bottom: 1px solid #fff; z-index: 3; }\
			.gme-tab input[type=radio]:checked ~ .gme-tab-label:after { box-shadow: -2px 2px 0 #fff; }\
			.gme-tab input[type=radio]:checked ~ .gme-tab-label:before { box-shadow: 2px 2px 0 #fff; }\
			.gme-fieldgroup { position: relative; border: 1px solid #ccc; border-radius: 6px; background: #eee; margin: 0.5em 0 1.5em; padding: 0.5em; }\
			.gme-fieldgroup h3 { position:absolute; top: -2.0em; left: 0.5em; padding: 0 0.5em; background: #eee; border-top: 1px solid #ccc; border-radius: 6px; z-index:1; display:inline-block; font-weight: bold; font-size: 12px; }\
			.gme-fieldgroup ul { margin: 0.5em 0; padding: 0; }\
			.gme-fieldgroup li { display: inline-block; margin: 0 -1px -1px 0; background: #ddd; border: 1px solid #ccc; border-radius: 6px; padding: 0 0.5em; ; font-style: normal; font-weight: 100; font-size: 12px; }\
			.gme-xhair { cursor: crosshair; }\
			.map-button-container { margin-right: 5em; }\
			#GME_apikeys_field label { display: block; }\
			#GME_apikeys_field label input { width: 75%; }',
		drag: '#cacheDetails .cacheImage { border: solid 1px #ccc; border-radius: 7px; padding-left: 5px; }\
			.moveable { cursor: move; box-shadow: 0 1px 4px rgba(102, 51, 255, 0.3); }'
	},
	env: {
		dragdrop: (document.createElement('span').draggable !== undefined),
		geolocation: !!navigator.geolocation,
		init: [],
		loggedin: (!!document.getElementById("ctl00_uxLoginStatus_divSignedIn") || !!document.getElementById("uxLoginStatus_divSignedIn")),
		page: "default",
		storage: false,
		xhr: (typeof GM_xmlhttpRequest === 'function') ? 'GM' : ((typeof GM === 'object' && typeof GM.xmlHttpRequest === 'function') ? 'GM4': '')
	},
	html: {
		config: '<section class="gme-tab">\
				<input type="radio" name="gme-tab-row" id="gme-tab-maps" checked />\
				<label class="gme-tab-label" for="gme-tab-maps">Map display</label>\
				<div class="gme-tab-content">\
					<div class="gme-fieldgroup">\
						<h3>Maps to show in selector widget</h3>\
						<ul id="GME_mapfields"></ul>\
						<label>Default map source: &nbsp;<select name="GME_map_default" id="GME_map_default"></select></label>\
						<label>Default hill shading source: &nbsp;<select name="GME_hill_shade_default" id="GME_hill_shade_default"></select></label>\
						<label>Default hill shading source: &nbsp;<select name="GME_hill_shade_default" id="GME_hill_shade_default"></select></label>\
					</div>\
					<div class="gme-fieldgroup">\
						<h3>Map API key</h3>\
						<div id="GME_apikeys_field"></div>\
					</div>\
				</div>\
			</section>\
			<section class="gme-tab">\
				<input type="radio" name="gme-tab-row" id="gme-tab-manage" />\
				<label class="gme-tab-label" for="gme-tab-manage">Manage maps</label>\
				<div class="gme-tab-content">\
					<div class="gme-fieldgroup">\
						<h3>Add map sources</h3>\
						<label>Mapsource: <input type="text" name="GME_map_custom" id="GME_map_custom">&nbsp;</label>\
						<div class="leaflet-control-gme"><button type="button" id="GME_custom_add" class="gme-button gme-button-wide gme-button-l gme-button-r" title="Add custom map source">Add</button> <a href="#GME_format" title="Map source format info" class="gme-button gme-button-wide gme-button-l">Mapsource format info</a><button type="button" id="GME_custom_export" title="Export custom map source JSON" class="gme-button gme-button-wide gme-button-r">Export custom maps</button></div>\
					</div>\
					<div class="gme-fieldgroup">\
						<h3>Remove map sources</h3>\
						<ul id="GME_mapfields_del"></ul>\
					</div>\
				</div>\
			</section>\
			<section class="gme-tab">\
				<input type="radio" name="gme-tab-row" id="gme-tab-other" />\
				<label class="gme-tab-label" for="gme-tab-other">Other</label>\
				<div class="gme-tab-content">\
					<div class="gme-fieldgroup">\
						<h3>Miscellaneous settings</h3>\
						<ul>\
							<li><label title="Only list unfound caches in search"><input type="checkbox" name="GME_filterFinds" id="GME_filterFinds" /> Filter finds</label></li>\
							<li><label><input type="checkbox" checked="checked" name="GME_osgbSearch" id="GME_osgbSearch" /> Enhance search</label></li>\
							<li><label title="Location widget constantly updates position"><input type="checkbox" name="GME_follow" id="GME_follow" /> FollowMe Mode</label></li>\
						</ul>\
						<label>Labels:\
							<select name="GME_labelStyle" id="GME_labelStyle">\
								<option value="names">Names</option>\
								<option value="codes" selected="selected">Codes</option>\
							</select>\
						</label>\
						<label>Scale:\
							<select name="GME_measure" id="GME_measure">\
								<option value="metric" selected="selected">Metric</option>\
								<option value="imperial">Imperial</option>\
							</select>\
						</label>\
						<label>Map brightness:\
							<input type="range" name="GME_brightness" id="GME_brightness" value="100" min="0" max="100" />\
						</label>\
					</div>\
				</div>\
			</section>\
			<section class="gme-tab">\
				<input type="radio" name="gme-tab-row" id="gme-tab-about" />\
				<label class="gme-tab-label" for="gme-tab-about">About</label>\
				<div class="gme-tab-content">\
					<div class="gme-fieldgroup">\
						<h3>Geocaching Map Enhancements</h3><br />\
						<p>v<span id="GME_version"></span> &copy; 2011-2018 James Inge. Geocaching Map Enhancements is licensed for reuse under the <a target="_blank" rel="noopener noreferrer" href="http://www.opensource.org/licenses/mit-license.php">MIT License</a>. For documentation, see <a target="_blank" rel="noopener noreferrer" href="http://geo.inge.org.uk/gme.htm">http://geo.inge.org.uk/gme.htm</a></p>\
						<p>Elevation and reverse geocoding data provided by <a target="_blank" rel="noopener noreferrer" href="http://www.geonames.org/">GeoNames</a> and used under a <a target="_blank" rel="noopener noreferrer" href="https://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0</a> (CC-BY) License.</p>\
						<p>Grid reference manipulation is adapted from code &copy; 2005-2014 Chris Veness (<a target="_blank" rel="noopener noreferrer" href="http://www.movable-type.co.uk/scripts/latlong-gridref.html">www.movable-type.co.uk/scripts/latlong-gridref.html</a>, used under a <a target="_blank" rel="noopener noreferrer" href="https://creativecommons.org/licenses/by/3.0/">Creative Commons Attribution 3.0</a> (CC-BY) License.</p>\
						<p>Photos provided by Geograph are copyright their respective owners - hover mouse over thumbnails or click through for attribution details. They may be re-used under a <a target="_blank" rel="noopener noreferrer" href="https://creativecommons.org/licenses/by-sa/2.0/">Creative Commons Attribution-ShareAlike 2.0</a> (CC-BY-SA) License.</p>\
					</div>\
				</div>\
			</section>\
			<div class="leaflet-control-gme">\
				<a href="#" class="gme-button gme-button-wide gme-button-l" rel="back" title="Cancel">Cancel</a><button type="button" class="gme-button gme-button-wide" id="GME_default" title="Reset to defaults">Defaults</button><button type="button" class="gme-button gme-button-wide gme-button-r" id="GME_set" title="Confirm settings">Save</button>\
			</div>',
		customInfo: '<p>Custom mapsources can be added by supplying entering a <a rel="external" href="http://www.json.org/">JSON</a> configuration string that tells GME what to call the map, where to find it, and how it is set up. e.g.</p>\
			<p><code>{"alt":"OS NPE (GB only)","tileUrl":"https://ooc.openstreetmap.org/npe/{z}/{x}/{y}.png", "minZoom":6, "maxZoom": 15, "attribution": "OpenStreetMap NPE" }</code></p>\
			<p>The <code>"alt"</code> and <code>"tileUrl"</code> parameters are mandatory. <code>"tileUrl"</code> can contain {x}, {y} and {z} for Google-style coordinate systems (also works with TMS systems like Eniro, but needs the <code>"scheme":"tms"</code> parameter), or {q} for Bing-style quadkeys. GME can also connect with WMS servers, in which case a <code>"layers"</code> parameter is required.</p>\
			<p>The other parameters are the same as those used by the <a rel="external" href="http://leafletjs.com/reference-versions.html">Leaflet API</a>, with the addition of a <code>"overlay":true</code> option, that makes the mapsource appear as a selectable overlay.</p>\
			<ul><li><a rel="external" href="http://geo.inge.org.uk/gme_config.htm">Detailed documentation</a></li><li><a rel="external" href="http://geo.inge.org.uk/gme_maps.htm">More mapsource examples</a></li></ul>',
		search: '<input type="text" placeholder="Address, coordinates, GC-code, keyword, etc." id="SearchBox_Text" title="Jump to a specific zoom level by typing zoom then a number. Zoom 1 shows the whole world, maxiumum zoom is normally 18-22. To search using a British National Grid reference, just type it in the search box and hit the button! You can use 2, 4, 6, 8 or 10-digit grid refs with the 2-letter prefix but no spaces in the number (e.g. SU12344225) or absolute grid refs with a comma but no prefix (e.g. 439668,1175316)." />\
			<button id="SearchBox_OS" title="Search">Search</button>\
			<div class="GME_search_results hidden">\
				<h3 class="GME_search_heading">GeoNames search results</h3>\
				<ul class="GME_search_list"></ul>\
				<p>Or try the <a href="#" class="GME_link_GSSearch">Geocaching.com search</a>\
			</div>'
	},
	script: {
		common: function () {
			var that = this, callbackCount = 0, load_count = 0, JSONP;
			function setEnv() {
				// The script waits for the Leaflet API to load, and will abort if it does not find it after a minute.
				var maxTries = 60,
					wait = 1000;
				switch (gmeConfig.env.page) {
				case "seek":
					if (typeof $ === "function") {
						gmeInit(gmeConfig.env.init);
						load();
						return;
					}
					break;
				case "hide":
					maxTries = Infinity;
					wait = 3000;
					if (window.map !== null && window.map !== undefined && typeof L === "object" && typeof $ === "function") {
						gmeInit(gmeConfig.env.init);
						window.setTimeout(load,500);
						return;
					}
					break;
				case "type":
					if (window.map !== null && window.map !== undefined && typeof L === "object" && typeof $ === "function") {
						gmeInit(gmeConfig.env.init);
						load();
						reload();
						$(".cache-type-selector button").click(reload);
						return;
					}
					break;
				case "maps":
					// Wait for the map to load and the default map selector to be added.
					if (typeof L === "object" && typeof $ === "function" && window.MapSettings && window.MapSettings.Map && window.MapSettings.Map._loaded && $(".leaflet-control-layers").length > 0) {
						gmeInit(gmeConfig.env.init);
						window.setTimeout(load,500);
						return;
					}
					break;
				default:
					if (typeof L === "object" && typeof $ === "function") {
						gmeInit(gmeConfig.env.init);
						window.setTimeout(load,500);
						return;
					}
					break;
				}

				if (load_count < maxTries) {
					window.setTimeout(setEnv, wait);
					load_count++;
					console.log("GME: Waiting for map API to load: " + load_count + "...");
				}
			}
			function gmeInit(scriptArray) {
				// Init routines that need either JQuery or Leaflet API, so must be run from load() rather than on script insertion.
				var initScripts = {
					"config": function () {
						if (gmeConfig.env.storage) {
							setConfig();
							$("#GME_set").bind("click", storeSettings);
							$("#GME_default").bind("click", setDefault);
							$("#GME_custom_add").bind("click", addCustom);
							$("#GME_custom_export").bind("click", exportCustom);
							$("li.li-user ul").append("<li class='li-settings'><a class='icon-settings' id='gme-config-link' href='#GME_config' title='Configure Geocaching Map Enhancements extension'>Geocaching Map Enhancements</a></li>");
						}
					},
					"drop": function () {
						$.fn.filterNode = function(name) {
							return this.find("*").filter(function () {
								return this.nodeName === name;
							});
						};
						L.GME_dropHandler = L.Control.extend(dropHandlerObj);
					},
					"map": function () {
						bounds_GB = new L.LatLngBounds(new L.LatLng(49,-9.5),new L.LatLng(62,2.3));
						bounds_IE = new L.LatLngBounds(new L.LatLng(51.2,-12.2),new L.LatLng(55.73,-5.366));
						bounds_NI = new L.LatLngBounds(new L.LatLng(54,-8.25),new L.LatLng(55.73,-5.25));
						bounds_CI = new L.LatLngBounds(new L.LatLng(49.1,-2.8),new L.LatLng(49.8,-1.8));
						bounds_DE = new L.LatLngBounds(new L.LatLng(47.24941,5.95459),new L.LatLng(55.14121,14.89746));
						L.GME_DistLine = L.Polyline.extend(polylineObj); 
						L.GME_QuadkeyLayer = L.TileLayer.extend(quadkeyLayerObj);
						L.GME_complexLayer = L.TileLayer.extend(complexLayerObj);
						L.GME_genericLayer = genericLayerFn;
					},
					"widget": function () {
						L.GME_Widget=L.Control.extend(widgetControlObj);
						if (window.Groundspeak && Groundspeak.Map && Groundspeak.Map.Control && Groundspeak.Map.Control.FindMyLocation) {
							L.GME_FollowMyLocationControl=Groundspeak.Map.Control.FindMyLocation.extend(locationControlObj);
						}
						L.GME_ZoomWarning=L.Control.extend(zoomWarningObj);
						if (L.LatLng.prototype.toUrl === undefined) {
							L.LatLng.prototype.toUrl = function() { return this.lat.toFixed(6) + "," + this.lng.toFixed(6); };
						}
						if ($.fancybox === undefined) {
							console.info("GME: Fetching Fancybox");
							$("head").append("<link rel='stylesheet' type='text/css' href='https://cdnjs.cloudflare.com/ajax/libs/fancybox/2.1.5/jquery.fancybox.min.css'><script type='text/javascript' src='https://cdnjs.cloudflare.com/ajax/libs/fancybox/2.1.5/jquery.fancybox.min.js'></script>");
						}
					}
				},
				j;
				
				for (j = 0; j < scriptArray.length; j++) {
					if (initScripts.hasOwnProperty(scriptArray[j]) && typeof initScripts[scriptArray[j]] === "function") {
						initScripts[scriptArray[j]]();
					}
				}
				console.log("GME init: " + scriptArray.join());
			}
			function b64encode(str) {
				if (typeof window.btoa === "function") {
					return btoa(encodeURIComponent(str));
				} else {
					return encodeURIComponent(str);
				}
			}
			function b64decode(str) {
				if (typeof window.atob === "function") {
					return decodeURIComponent(window.atob(str));
				} else {
					return decodeURIComponent(str);
				}
			}
			function DMM(ll) {
				var latDeg = ll.lat < 0 ? Math.ceil(ll.lat) : Math.floor(ll.lat),
					lngDeg = ll.lng < 0 ? Math.ceil(ll.lng) : Math.floor(ll.lng);
				return (ll.lat < 0 ? "S" : "N") + Math.abs(latDeg) + " " + (60 * Math.abs((ll.lat - latDeg))).toFixed(3) + (ll.lng < 0 ? " W" : " E") + Math.abs(lngDeg) + " " + (60 * Math.abs((ll.lng - lngDeg))).toFixed(3);
			}
			function formatDistance(dist) {
				var formatted = 0;
				if (that.parameters.measure === "metric") {
					if (dist > 10000) {
						formatted = (dist/1000).toFixed(2) + " km";
					} else {
						if (dist > 1000) {
							formatted = (dist/1000).toFixed(2) + " km";
						} else {
							formatted = Math.round(dist)+" m";
						}
					}
				} else {
					if (dist > 16093.44) {
						formatted = Math.round(dist/1609.344) + " mi";
					} else {
						if (dist > 1609.344) {
							formatted = (dist/1609.344).toFixed(1) + " mi";
						} else {
							formatted = Math.round(dist * 3.2808)+" ft";
						}
					}
				}
				return formatted;
			}
			function htmlEntities(text) {
				return text
					.replace(/&/g, "&amp;")
					.replace(/\"/g, "&quot;")
					.replace(/'/g, "&apos;")
					.replace(/</g, "&lt;")
					.replace(/>/g, "&gt;");
			}
			function validCoords(c1, c2) {
				var lat, lng;
				if (c1 === undefined) {
					return false;
				}
				if (c1.hasOwnProperty("lat") && c1.hasOwnProperty("lng")) {
					lat = c1.lat;
					lng = c1.lng;
				} else {
					if (c2 !== undefined) {
						lat = c1;
						lng = c2;
					}
				}
				if (lat !== null && lng !== null && !isNaN(+lat) && !isNaN(+lng) && lat >= -90 && lat <= 90) {
					return true;
				}
				return false;
			}
			function parseCoords(text) {
				var lat=0, lng=0, num=0,
				c = text.replace(/[^\-SsWw0-9\.\s]/g," ").trim().match(/^([S\-])?\s*(\d{1,2}(\.\d*){0,1}|\.\d*)(\s+(\d{0,2}(\.\d*){0,1})){0,1}(\s+(\d{0,2}(\.\d*){0,1})){0,1}\s*([S\-])?\s+([W\-])?\s*(\d{1,3}(\.\d*){0,1}|\.\d*)(\s+(\d{0,2}(\.\d*){0,1})){0,1}(\s+(\d{0,2}(\.\d*){0,1})){0,1}\s*([W\-])?$/i);
				if (c) {
					num = (c[2]?1:0) + (c[5]?1:0) + (c[8]?1:0) + (c[12]?1:0) + (c[15]?1:0) + (c[18]?1:0);
					switch(num) {
						case 6:
							break;
						case 4:
							if (c[15] === undefined) { c[15] = c[12]; c[12] = c[8]; c[8] = undefined; }
							break;
						case 2:
							if (c[12] === undefined && c[5]) { c[12] = c[5]; c[5] = undefined; }
							break;
						default:
							alert("Couldnt understand coordinates");
							return false;
					}
					if (c[2] !== undefined) { lat = +c[2]; }
					if (c[5] !== undefined) { lat += c[5]/60; }
					if (c[8] !== undefined) { lat += c[8]/3600; }
					if (c[1] !== undefined || c[10] !== undefined) { lat *= -1; }
					if (c[12] !== undefined) { lng = +c[12]; }
					if (c[15] !== undefined) { lng += c[15]/60; }
					if (c[18] !== undefined) { lng += c[18]/3600; }
					if (c[11] !== undefined || c[20] !== undefined) { lng *= -1; }
				}
				if (validCoords(lat, lng)) {
					return {lat:lat,lng:lng};
				}
				alert("Invalid coordinates");
				return false;
			}
			function getHomeCoords() {
				var c, h = document.getElementById("ctl00_ContentBody_lnkPrintDirectionsSimple");
				if (window.MapSettings && MapSettings.User && validCoords(MapSettings.User.Home)) {
					return new L.LatLng(MapSettings.User.Home.lat, MapSettings.User.Home.lng);
				}
				if (validCoords(window.homeLat, window.homeLon)) {
					return new L.LatLng(window.homeLat, window.homeLon);
				}
				if (h && h.href) {
					c = h.href.match(/(?:saddr=)(-?\d{1,2}\.\d*),(-?\d{1,3}\.\d*)/);
					if (c !== null && c.length === 3 && validCoords(c[1], c[2])) {
						return new L.LatLng(c[1], c[2]);
					}
				}
				return false;
			}
			function validURL(url) {
				return (/^(http|https|ftp)\:\/\/([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&amp;%\$\-]+)*@)*((25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])|localhost|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(\:[0-9]+)*(\/($|[a-zA-Z0-9\.\,\?'\\\+&amp;%\$#\=~_\-]+))*$/).test(url);
			}

			if (window.console === undefined) {
                var logFn = function (text) {};
				window.console = {
                    error: logFn,
                    log: logFn,
                    info: logFn,
                    warn: logFn
                };
			}
			
			if (gmeConfig.env.xhr) {
				JSONP = function (url, id) {
					console.log("GME: Using GM_xhr to fetch " + url);
					var s = document.getElementById("gme_jsonp_node");
					if (!s) {
						s = document.createElement("script");
						s.id = "gme_jsonp_node";
						document.documentElement.firstChild.appendChild(s);
					}
					s.type = "text/x-gme-jsonp";
					s.text = url;
					s.setAttribute("data-gme-callback", id);
					document.dispatchEvent(new Event("GME_XHR_event"));
				};
				document.addEventListener("GME_XHR_callback", function (e) {
					var s = document.getElementById("gme_jsonp_node"),
						callback = s.getAttribute("data-gme-callback");
					if (typeof window[callback] === "function") {
						try {
							window[callback](JSON.parse(s.text));
						} catch (e) {
							console.error("Error processing JSON callback " + callback + ": " + e);
						}
					} else {
						console.warn("Unexpected request to JSON callback handler: Couldn't find callback function " + callback);
					}
					return false;
				});
			} else {
				JSONP = function (url, id) {
					console.log("GME: Using JSONP to fetch " + url);
					if (validURL(url)) {
						var s=document.createElement("script");
						s.type="text/javascript";
						if (id) { s.id=id; }
						s.src=url;
						document.documentElement.firstChild.appendChild(s);
					}
				};
			}

			gmeConfig.env.home = getHomeCoords();
			
			this.parameters = gmeConfig.parameters;
			this.getVersion = function() { return gmeConfig.parameters.version; };
			this.getGeograph = function(coords) {
				var callprefix="GME_geograph_callback", call, host = "";
				function searchLink(coords) {
					// URIs for website search pages.
					if (coords === undefined) { return false; }
					var host="";
					if (bounds_GB.contains(coords) || bounds_IE.contains(coords)) {
						host="https://geograph.org.uk/";
					}
					if (bounds_CI.contains(coords)) {
						host="https://www.geograph.org.gg/";
					}
					if (bounds_DE.contains(coords)) {
						host="https://geo-en.hlipp.de/";
					}
					return host?[host,"search.php?location=", coords.toUrl()].join(""):false;
				}
				function makeCallback(callname) { callbackCount++; return function(json) {
					var html, i, p;
					if (json.items && json.items.length>0) {
						html = ["<h3>Geograph images near ", DMM(coords), "</h3><p>"].join("");
						for (i=json.items.length-1;i>=0;i--) {
							p = json.items[i];
							html += ["<a target='_blank' rel='noopener noreferrer' href='",encodeURI(p.link),"' style='margin-right:0.5em;' title='", htmlEntities(p.title) + " by " + htmlEntities(p.author), "'>",p.thumbTag,"</a>"].join("");
						}
						html += ["</p><p><a target='_blank' rel='noopener noreferrer' href='",searchLink(coords),"'>Search for more photos nearby on Geograph</a></p><p style='font-size:90%;'>Geograph photos are copyrighted by their owners and available under a <a href='https://creativecommons.org/licenses/by-sa/2.0/'>Creative Commons licence</a>. Hover mouse over thumbnails for more details, or click through for full images.</p>"].join("");
						$.fancybox(html);
					} else {
						$.fancybox(["<p>No photos found nearby. <a target='_blank' rel='noopener noreferrer' href='",searchLink(coords),"'>Search on Geograph</a></p>"].join(""));
					}
					$("#"+callname).remove();
					if (window[callname] !== undefined) { delete window[callname]; }
				};}
				if (validCoords(coords) && this.isGeographAvailable(coords)) {
					if (!bounds_CI.contains(coords) && (bounds_GB.contains(coords) || bounds_IE.contains(coords))) {
						host="https://api.geograph.org.uk/";
                        call = callprefix + callbackCount;
                        window[call] = makeCallback(call);
                        JSONP(host + "syndicator.php?key=geo.inge.org.uk&location=" + coords.toUrl() + "&format=JSON&callback=" + call, call);
					} else {
						window.open(searchLink(coords), "_blank");
					}
				} else {
					console.error("GME: Bad coordinates to getGeograph");
				}
			};
			this.getHeight = function(coords) {
				var callprefix="GME_height_callback",call;
				function makeCallback(callname) { callbackCount++; return function (json) {
					if (typeof json.astergdem === "number" && typeof json.lat === "number" && typeof json.lng === "number") {
						var h, m;
						if (json.astergdem === -9999) {
							m = "<p><strong>Spot Height</strong><br/>(Ocean)</p>";
						} else {
							h = that.parameters.measure==="metric"?json.astergdem+" m":Math.round(json.astergdem*3.2808)+" ft";
							m = ["<p><strong>Spot Height</strong><br/>Approx ",h," above sea level</p>"].join("");
						}
						$.fancybox(m);
					}
					$("#"+callname).remove();
					if (window[callname] !== undefined) { delete window[callname]; }
				};}
				if (validCoords(coords)) {
					call = callprefix + callbackCount;
					window[call] = makeCallback(call);
					JSONP(["http://api.geonames.org/astergdemJSON?lat=",coords.lat,"&lng=",coords.lng,"&username=gme&callback=",call].join(""), call);
				} else {
					console.error("GME: Bad coordinates to getHeight");
				}
			};
			this.isGeographAvailable = function(coords) {
				return	bounds_GB.contains(coords) || bounds_DE.contains(coords) || bounds_IE.contains(coords) || bounds_CI.contains(coords);
			};
			this.isInUK = function(coords) {
				if (bounds_GB.contains(coords)) {
					if (bounds_IE.contains(coords)) {
						if (bounds_NI.contains(coords)) {
							return true;
						}
						return false;
					}
					return true;
				}
				return false;
			};
			if (gmeConfig.env.geolocation) {
				this.seekHere = function() {
					function hereCallback(pos) {
						that.seekByLatLng({lat:pos.coords.latitude, lng:pos.coords.longitude});
						$("#GME_hereSub").val("Go");
					}
					function hereError(err) {
						if (err.code === 2) {
							alert("Current location not available");
						}
						if (err.code === 3) {
							alert("Timed out finding current location");
						}
						$("#GME_hereSub").val("Go");
					}
					$("#GME_hereSub").val("Waiting for location...");
					navigator.geolocation.getCurrentPosition(hereCallback, hereError, {timeout: 60000, maximumAge: 30000});
					return false;
				};
			}
			this.seekByLatLng = function(latlng) {
				if (validCoords(latlng)) {
					var url = ["https://www.geocaching.com/seek/nearest.aspx?origin_lat=",latlng.lat,"&origin_long=",latlng.lng, that.parameters.filterFinds?"&f=1":""].join("");
					window.open(url, "_blank");
				} else {
					console.error("GME: Invalid coordinates for search");
				}
			};
		},
		config: function () {
			function addSources(json){
				function setSrc(src) {
					if (src.alt && src.tileUrl) {
						var m = that.parameters.maps.concat(src);
						that.parameters.maps = m;
						return 1;
					}
					alert("Map source must include at least \"alt\" and \"tileUrl\" parameters");
					return 0;
				}
				var i,updated=0;
				if (json.length === undefined) {
					updated += setSrc(json);
				} else {
					for (i = 0; i < json.length; i++) {
						updated += setSrc(json[i]);
					}
				}
				if (updated > 0) {
					setConfig();
					$("#gme-tab-maps")[0].checked = true;
				}
			}
			function addCustom(){
				try{
					var n = JSON.parse(document.getElementById("GME_map_custom").value);
					addSources(n);
				} catch (e) {
					alert("Map source string must be valid JSON.");
					return;
				}
			}
			function exportCustom(){
				$.fancybox($("<p/>").text(JSON.stringify(that.parameters.maps)).html());
			}
			function setDefault(){
				if (localStorage.GME_custom) { delete localStorage.GME_custom; }
				if (localStorage.GME_parameters) { delete localStorage.GME_parameters; }
				if (localStorage.GME_cache) { delete localStorage.GME_cache; }
				refresh();
			}
			function refresh(config) {
				var dest = "https://www.geocaching.com/map/#",
					mapLink = document.getElementById("map_linkto"),
					uri;
				if (config) {
					dest += "GME_config";
				}
				if (mapLink) {
					uri = mapLink.value;
					if (uri) {
						dest += uri.replace(/^http:\/\/coord.info\/map/, "");
					}
					document.location.href = dest;
				} else {
					document.location.hash = "";
				}
				window.location.reload(false);
				return false;
			}
			function setConfig() {
//					console.log("setConfig");
					var i,mapfields = "",shadingSelect = "<option value=''>none</option>",mapfields_del = "",mapselect = "",alt = "",overlay="", sel="", overSel="",allMaps = that.parameters.maps,allApiKeys = that.parameters.apiKeys;

					for (i = 0; i < allMaps.length; i++) {
						alt = allMaps[i].alt;
						overlay = allMaps[i].overlay;
						if (!overlay) { mapselect += "<option value='" + htmlEntities(alt) + "'>" + htmlEntities(alt) + "</option>"; }
						else { shadingSelect += "<option value='" + htmlEntities(alt) + "'>" + htmlEntities(alt) + "</option>"; }
						mapfields += "<li><label><input type='checkbox' " + (allMaps[i].ignore ? "" : "checked='checked' ") + "name='" + htmlEntities(alt) + "' id='checkbox-" + i + "' /> " + htmlEntities(alt) + (overlay ? " (Overlay)" : "") + "</label></li>";
					}

					// API keys
					const mapsWithApiKey = allMaps.filter(function(map) {return map.apiKey});
//					mapsWithApiKey.forEach((map) => {
					mapsWithApiKey.forEach(function(map) {
						const existingApiKey = allApiKeys && allApiKeys[map.apiKey] ? allApiKeys[map.apiKey] : "";
						const label = document.createElement("label");
//						label.innerHTML = $(map.apiKey).html+'&nbsp;';//'OpenCycleMap&nbsp;<input type="text" name="OpenCycleMap">';//`${map.apiKey}&nbsp`;//'OpenCycleMap&nbsp;'//&#96;${map.apiKey}&nbsp;&#96;;
//						debugger;
//						label.innerHTML = `${map.apiKey}&nbsp`;
						label.innerHTML = map.apiKey+'&nbsp;';
						const input = document.createElement("input");
						input.type = "text";
						input.name = map.apiKey;
						input.value = existingApiKey;
						label.appendChild(input);
						$("#GME_apikeys_field").append(label);
//						console.log("label.innerHTML=="+label.innerHTML);
					}
					);

					if (allMaps.length > 0) {
						for (i = 0; i < allMaps.length; i++) {
							alt = allMaps[i].alt;
							mapfields_del += "<li><label><input type='checkbox' name='" + htmlEntities(alt) + "' id='checkbox-del-" + i + "' /> " + htmlEntities(alt) + (allMaps[i].overlay ? " (Overlay)" : "") + "</label></li>";
						}
					} else {
						mapfields_del = "&lt; No custom maps installed &gt;";
					}
					$("#GME_mapfields").html(mapfields);
					$("#GME_mapfields_del").html(mapfields_del);
					$("#GME_map_default").html(mapselect);
					$("#GME_hill_shade_default").html(shadingSelect);
					sel = $("#GME_map_default").children();
					for (i = sel.length - 1; i > -1; i--) {
						if (sel[i].value === that.parameters.defaultMap) {
							sel[i].selected = "selected";
						}
					}
					overSel = $("#GME_hill_shade_default").children();
					for (i = overSel.length - 1; i > -1; i--) {
						if (overSel[i].value === that.parameters.defaultHillShade) {
							overSel[i].selected = "selected";
						}
					}
					$("#GME_filterFinds").attr("checked", that.parameters.filterFinds);
					$("#GME_osgbSearch").attr("checked", that.parameters.osgbSearch);
					$("#GME_follow").attr("checked", that.parameters.follow);
					$("#GME_labelStyle").val(that.parameters.labels);
					$("#GME_measure").val(that.parameters.measure);
					$("#GME_brightness").val(that.parameters.brightness * 100);
					$("#GME_version").html(that.parameters.version);

			}
			function storeSettings(){
					var i, j, list, apiKeys;
					that.parameters.defaultMap = $("#GME_map_default")[0].value;
					that.parameters.defaultHillShade = $("#GME_hill_shade_default")[0].value;
					list = $("#GME_mapfields input");
					for (i = list.length - 1; i >= 0; i--) {
						for (j = that.parameters.maps.length - 1; j >= 0; j--) {
							if (that.parameters.maps[j].alt === list[i].name) {
								that.parameters.maps[j].ignore = !list[i].checked;
							}
						}
					}
					for (j = that.parameters.maps.length - 1; j >= 0; j--) {
						if (that.parameters.maps[j].alt === that.parameters.defaultMap) {
							that.parameters.maps[j].ignore = false;
						}
					}
					list = $("#GME_mapfields_del input");
					for (i = list.length - 1; i >= 0; i--) {
						if (list[i].checked === true) {
							for (j = that.parameters.maps.length - 1; j >= 0; j--) {
								if (that.parameters.maps[j].alt === list[i].name) {
									that.parameters.maps.splice(j, 1);
									break;
								}
							}
						}
					}

					if (!that.parameters.apiKeys) {
						that.parameters.apiKeys = {};
					}
					apiKeys = $("#GME_apikeys_field label input");
					for (var ak = 0; ak < apiKeys.length; ak++) {
						const field = apiKeys[ak];
						if (field.value) {
							that.parameters.apiKeys[field.name] = field.value;
						} else if (that.parameters.apiKeys[field.name]) {
							delete that.parameters.apiKeys[field.name];
						}
					}

					that.parameters.brightness = $("#GME_brightness").val() / 100;
					that.parameters.filterFinds = $("#GME_filterFinds")[0].checked ? true : false;
					that.parameters.follow = $("#GME_follow")[0].checked ? true : false;
					that.parameters.labels = $("#GME_labelStyle")[0].value;
					that.parameters.measure = $("#GME_measure")[0].value;
					that.parameters.osgbSearch = $("#GME_osgbSearch")[0].checked ? true : false;
					localStorage.setItem("GME_parameters", JSON.stringify(that.parameters));
					refresh();
			}
		},
		cssTransitionsFix: function () {
		//	<bugfix>
			// Work around bug that breaks JQuery Mobile dialog boxes in Opera 12.
			if (window.$ && $.support) {
				$.support.cssTransitions = false;
			}
		//	</bugfix>
		},
		dist: function () {
			$("#lblDistFromHome").parent().append("<br/><span id='gme-dist'><a href='#' id='gme-dist-link'>Check distance from here</a></span>");
			$("#gme-dist-link").click(function () {
				var there = new LatLon(mapLatLng.lat, mapLatLng.lng),
					rose = [[22.5,67.5,112.5,157.5,202.5,247.5,292.5,337.5],["N","NE","E","SE","S","SW","W","NW"]],
					watcher;
				function found(pos) {
					var here = new LatLon(pos.coords.latitude, pos.coords.longitude),
					bearing = here.bearingTo(there),
					dir = "N", i;
					for (i = 0; i < 8; i++){
						if (bearing < rose[0][i]){
							dir = rose[1][i];
							break;
						}
					}
					$("#gme-dist").html("<img style='vertical-align:text-bottom' alt='" + dir + "' src='/images/icons/compass/" + dir + ".gif'> " + dir + " " + formatDistance(here.distanceTo(there)*1000) + " from here at bearing " + Math.round(bearing) + "&deg;");
				}
				function lost() {
					if (watcher) {
						navigator.geolocation.clearWatch(watcher);
					}
					alert("GME couldn't detect your location.\nDisable FollowMe mode in Geocaching Map Enhancements if this error pops up repeatedly.");
				}
				if (that.parameters.follow) {
					watcher = navigator.geolocation.watchPosition(found, lost, {timeout: 60000, maximumAge: 30000});
				} else {
					navigator.geolocation.getCurrentPosition(found, lost, {timeout: 60000, maximumAge: 30000});
				}
				return false;
			});
		},
		drag: function () {
			that.dragStart = function (event) {
				function GME_formatLOC(wpts) {
					return wpts ? ['<?xml version="1.0" encoding="UTF-8"?>\n<loc version="1.0" src="Geocaching Map Enhancements v' + that.getVersion() + '">' + wpts.join('\n') + '</loc>'].join('\n'):null;
				}
				function GME_formatLOC_wpt(id, desc, coords, type, link) {
					if (id && desc && coords) {
						var t="Geocache",
							l=link ? ('\n\t<link text="' + link.desc + '">' + link.href + '</link>') : "";
						switch(type) {
							case "Original Coordinates": t=type; break;
							case 217: t="Parking Area"; break;
							case 218: t="Question to Answer"; break;
							case 219: t="Stages of a Multicache"; break;
							case 220: t="Final Location"; break;
							case 221: t="Trailhead"; break;
							case 452: t="Reference Point"; break;
						}
						return ('<waypoint>\n\t<name id="' + id + '"><![CDATA[' + desc + ']]></name>\n\t<coord lat="' + coords.lat + '" lon="' + coords.lng + '"/>\n\t<type>' + t + '</type>' + l + '\n</waypoint>');
					}
					console.warn("GME: Missing cache data - id:", id , "desc:", desc, "coords:", coords);
					return null;
				}
				var c, dataURI, dt, i, locfmt,
					id = $("#ctl00_ContentBody_CoordInfoLinkControl1_uxCoordInfoCode")[0].innerHTML,
					loc = [GME_formatLOC_wpt(id, cache_coords.primary[0].name, cache_coords.primary[0], cache_coords.primary[0].type,{desc:"Cache Details",href:"https://coord.info/"+id})];
				for (i = cache_coords.additional.length-1; i >= 0; i--) {
					c = cache_coords.additional[i];
					loc.push(GME_formatLOC_wpt(c.pf + id.slice(2), [c.name,$("#awpt_"+c.pf).parent().parent().next().children()[2].innerHTML.trim()].join(" "), c, c.type));
				}
				if (cache_coords.primary[0].isUserDefined) {
					loc.push(GME_formatLOC_wpt("GO"+id.slice(2), cache_coords.primary[0].name, {lat:cache_coords.primary[0].oldLatLng[0], lng:cache_coords.primary[0].oldLatLng[1]}, "Original Coordinates",{desc:"Cache Details",href:"https://coord.info/"+id}));
				}
				locfmt = GME_formatLOC(loc);
				dataURI = "data:application/xml-loc," + encodeURIComponent(locfmt);
				dt = event.originalEvent.dataTransfer;
				if (window.DataTransfer !== undefined && dt.constructor === window.DataTransfer) {
					dt.setData("application/gme-cache-coords",JSON.stringify(cache_coords));
					dt.setData("application/xml-loc", locfmt);
					dt.setData("text/x-moz-url",dataURI+"\nGME_waypoints.loc");
					dt.setData("DownloadURL","application/xml-loc:GME_waypoints.loc:"+dataURI);
				}
				dt.setData("text/uri-list",dataURI);
				dt.setData("Text",locfmt);
				dt.effectAllowed="copy";
				dt.setDragImage($('a[title="About Cache Types"] img')[0],0,0);
			};
		},
		drop: function () {
			var dropHandlerObj = {
				onAdd:function (map) {
					var container = $(map.getContainer());
					this._map = map;
					container.on("drop",this.drop(map));
					container.on("dragover",this.dragOver);
					return document.createElement("div");
				},
				onRemove:function (map) {
					var container = $(map.getContainer());
					container.off("drop",this.drop(map));
					container.off("dragover",this.dragOver);
				},
				drop:function (map) { return function (e) {
					function typeToIcon(t) {
						var j, type=t;
						for (j = wptTypes.length - 1; j>=0; j--) {
							type = type.replace(wptTypes[j][0],wptTypes[j][1]);
						}
						return type;
					}
					function parseLOC(text) {
						var i, l, w, t, len, lat, lng, name, points={primary:[], additional:[]}, wpts = $($.parseXML(text)).find("waypoint");
						for (i=0,len=wpts.length;i<len;i++){
							w=$(wpts[i]);
							lat=w.find("coord").attr("lat");
							lng=w.find("coord").attr("lon");
							name=w.find("name").attr("id") + ": " + w.find("name").text().trim();
							if (isNaN(+lat)||isNaN(+lng)||lat < -90||lat >90) { return false; }
							t = w.find("type").text();
							if (/Geocache/i.test(t)) {
								points.primary.push({ lat:lat, lng:lng, name:name, type:2 });
							} else {
								l = points.primary.length;
								if (l && /Original Coordinates/i.test(t)) {
									points.primary[l-1].oldLatLng = [lat, lng];
									points.primary[l-1].isUserDefined = true;
								} else {
									points.additional.push({ lat:lat, lng:lng, name:name, type:typeToIcon(t) });
								}
							}
						}
						return(points.additional.length + points.primary.length > 0)?points:false;
					}
					function readLOC(e) {
						var data = e.target.result, pts = parseLOC(data);
						if (pts) {
							console.info("GME: Received LOC file");
							GME_displayPoints(pts,map,"dragdrop");
						}
					}
					window.parseGPX = function parseGPX(text, filename) {
						var h,dashc,farba, d, i, j, k, w, r, t, lat, lng, len, n, name="", poly, type, points={primary:[], additional:[], routes:[]}, gpx = $($.parseXML(text)), wpts = gpx.find("wpt"), tracks = gpx.find("trk"), segs, routes = gpx.find("rte");
//						debugger;
						for (i=0,len=wpts.length;i<len;i++){
							w=$(wpts[i]);
							lat=w.attr("lat");
							lng=w.attr("lon");
							n=w.filterNode("name");
							d=w.filterNode("desc");
							name=n.length>0?n[0].textContent:"Point "+i;
							name+=(n.length>0&&d.length>0)?" : ":"";
							name+=d.length>0?d[0].textContent:"";
							if (isNaN(+lat)||isNaN(+lng)||lat < -90||lat >90) { return false;}
							t = w.find("sym").text();
							if (/Geocache/i.test(t)) {
								t = w.filterNode("groundspeak:type");
								if (t.length > 0) {
									type = t[0].textContent;
								} else {
									type = "Geocache";
								}
							} else {
								type = t;
							}
							points[/Geocache/i.test(t)?"primary":"additional"].push({ lat:lat, lng:lng, name:name, type:typeToIcon(type) });
						}
						for (i=routes.length-1;i>=0;i--) {
							poly = [];
							r = $(routes[i]);
							n=r.filterNode("name");
							name=n.length>0?n[0].textContent:"Route "+i;
							wpts = r.find("rtept");
							for (j = wpts.length-1;j>=0;j--) {
								w = $(wpts[j]);
								poly.push(new L.LatLng(w.attr("lat"), w.attr("lon")));
							}
//						debugger;							
						}
						
						for (i=tracks.length-1;i>=0;i--) {
							poly = [];
							r = $(tracks[i]);
							segs = r.find("trkseg");
							d = r.filterNode("desc");
							farba="#0000FF";
							dashc='';
							h=3;
							if (d.length > 0 )
							{
							if (d[0].textContent === "KORIDOR-L"){
							farba="#00FF00"	;dashc='8,8'; h=3;}
							else
							if (d[0].textContent === "KORIDOR-R"){
							farba="#00FF00"	; dashc='8,5'; h=3;}
							else
							{farba="#0000FF"; dashc=''; h=5;}
							}
				for (j = segs.length - 1; j >= 0; j--) {
	n = r.filterNode("name");
	name = [(n.length > 0) ? n[0].textContent : "Track " + i, " segment ", j].join("");
	wpts = $(segs[j]).find("trkpt");

	poly = [];  // nezabudni resetnúť poly pre každý segment

	for (k = wpts.length - 1; k >= 0; k--) {
		w = $(wpts[k]);
		var lat = parseFloat(w.attr("lat"));
		var lon = parseFloat(w.attr("lon"));
		var eleTag = w.find("ele");
		var ele = eleTag.length ? parseFloat(eleTag.text()) : null;

		var point = new L.LatLng(lat, lon);
		if (ele !== null) point.alt = ele;  // nastav .alt ak existuje

		poly.push(point);
	}
								points.routes.push({
									name: name, 
									points: poly,
									color: farba,
									distance: computeDistance(poly),
									ascending: computeAscend(poly),
									descending: computeDescend(poly), 
									filename: filename, 
									dash: dashc,
									weight: h});								
								}
						}
						return(points.additional.length + points.primary.length + points.routes.length> 0)?points:false;
					}
					function readGPX(e, currentFilename) {
//						debugger; // Tu sa vykonávanie preruší
						var data = e.target.result, pts = parseGPX(data,currentFilename);
						if (pts) {
							console.info("GME: Received GPX file: " + currentFilename);
							GME_displayPoints(pts,map,"dragdrop",currentFilename);
						}
					}
					
					e.stopPropagation();
					e.preventDefault();
					var i, data, dt=e.originalEvent.dataTransfer, file, files = dt.files, pts, reader;
					try {
						data = dt.getData("application/gme-cache-coords");
						if (data) {
							console.info("GME: Received GME data");
							GME_displayPoints(JSON.parse(data),map,"dragdrop");
							return;
						}
						data = dt.getData("text/plain");
						if (data) {
							pts = parseLOC(data);
							if (pts) {
								console.info("GME: Received LOC text");
								GME_displayPoints(pts,map,"dragdrop");
								return;
							}
							pts = parseGPX(data);
							if (pts) {
								console.info("GME: Received GPX text");
								GME_displayPoints(pts,map,"dragdrop");
								return;
							}
						}
					} catch (E) { console.warn("GME: Drop: " + E); }
					for (i=files.length-1; i>=0; i--){
						file = files[i];
						if (/application\/xml-loc/.test(file.type)||/\.loc$/i.test(file.name)) {
							reader = new FileReader();
							reader.onload = readLOC;
							reader.readAsText(file);
						} else {
							if (/application\/xml-gpx/.test(file.type)||/\.gpx$/i.test(file.name)) {
								reader = new FileReader();
//								reader.onload = readGPX;
								reader.onload = function(e) {
								readGPX(e, file.name); // teraz je filename správne odovzdaný
								};
								reader.readAsText(file);
							} else {
								console.warn("GME: Dropped file not recognised: " + file.name + ", (type: " + file.type + ")");
							}
						}
					}
				};},
				dragOver:function (e) {
					var dt=e.originalEvent.dataTransfer;
					function contains(array, value) {
						if (array.indexOf) {
							return array.indexOf(value) >= 0;
						}
						if (array.contains) {
							return array.contains(value);
						}
						console.warn("GME: couldn\'t determine type of dragged data. Accepting anyway.");
						return true;
					}
					if (dt && dt.types) {
						try {
							if (contains(dt.types, "application/gme-cache-coords") || contains(dt.types,"application/xml-gpx") || contains(dt.types,"application/xml-loc") || contains(dt.types,"text/plain") || contains(dt.types,"Files")){
								e.preventDefault();
								return false;
							}
						} catch (e) {
							console.error("GME: dragOver:", e);
						}
					}
				}
			};
		},
		loadDefault: function () {
			if (typeof window.$ === "function") {
				gmeInit(gmeConfig.env.init);
			}
		},
		labels: function () {
			function GME_load_labels(control, div) {
				function labelHandler() {
					var action = this.getAttribute("data-gme-action"), cache = this.getAttribute("data-gme-cache");
					switch (action) {
						case "panTo":
							if (control.labels.labels[cache]) {
								control._map.panTo(control.labels.labels[cache][2]);
							}
							break;
						case "refresh":
							control.labels.refresh();
							break;
						case "clear":
							control.labels.removeLabels();
							break;
						case "auto":
							control.labels.toggleAuto();
							break;
						case "show":
							control.labels.toggleShow();
							break;
					}
					return false;
				}
				L.GME_identifyLayer = L.Class.extend({
					initialize: function (latlng, options) {
						L.Util.setOptions(this, options);
						this._latlng = latlng;
					},
					onAdd: function (map) {
						this._map = map;
						this._el = L.DomUtil.create("div", "gme-identify-layer leaflet-zoom-hide");
						this._el.innerHTML = this.options.label;
						this._el.title = this.options.desc;
						this._el.style.position = "absolute";
						map.getPanes().overlayPane.appendChild(this._el);
						map.on("viewreset", this._reset, this);
						this._reset();
					},
					onRemove: function (map) {
						map.getPanes().overlayPane.removeChild(this._el);
						map.off("viewreset", this._reset, this);
					},
					options: {
						label: "Cache",
						desc: "Long cache name"
					},
					setPosition: function (ll) {
						this._latlng = ll;
						this._reset();
					},
					_reset: function () {
						if (this._map) {
							var pos = this._map.latLngToLayerPoint(this._latlng);
							L.DomUtil.setPosition(this._el, pos);
						}
					}
				});
				control.labels = {
					showLabels: false,
					autoUpdate: false,
					labels: {},
					labelLayer: new L.LayerGroup(),
					clearLabels:function () {
						control._map.removeLayer(control.labels.labelLayer);
					},
					displayLabels:function () {
						control._map.addLayer(control.labels.labelLayer);
					},
					refresh:function () {
						if (!(window.MapSettings && MapSettings.MapLayers && MapSettings.MapLayers.UTFGrid)) {
							return;
						}
						var i, coords, tiles = $(".leaflet-tile-pane .leaflet-layer img[src*='geocaching.com/map.png']");
						for (i = tiles.length-1; i>=0; i--) {
							coords = tiles[i].src.match(/x=(\d+)&y=(\d+)&z=(\d+)/);
							if (coords && !MapSettings.MapLayers.UTFGrid._cache.hasOwnProperty(([coords[3],coords[1],coords[2]].join("_")))) {
								MapSettings.MapLayers.UTFGrid._loadTile(coords[3],coords[1],coords[2]);
							}
						}
						setTimeout(control.labels.refreshLabels, 500);
					},
					refreshLabels:function () {
						var c, p, q, r, tile, tilepos, tileref, gridref, zoom = control._map.getZoom();
						if (!(window.MapSettings && MapSettings.MapLayers && MapSettings.MapLayers.UTFGrid)) {
							return;
						}
						for (p in MapSettings.MapLayers.UTFGrid._cache) {
							if (MapSettings.MapLayers.UTFGrid._cache.hasOwnProperty(p)) {
								tileref = p.split("_");
								if (tileref.length === 3) {
									tile = $("img[src*='x=" + tileref[1] + "&y=" + tileref[2] + "&z=" + tileref[0] + "']")[0];
									if (tile) {
										tilepos = L.DomUtil.getPosition(tile);
										if (MapSettings.MapLayers.UTFGrid._cache[p]) {
											for (q in MapSettings.MapLayers.UTFGrid._cache[p].data) {
												if (MapSettings.MapLayers.UTFGrid._cache[p].data.hasOwnProperty(q)) {
													for (r in MapSettings.MapLayers.UTFGrid._cache[p].data[q]) {
														if (MapSettings.MapLayers.UTFGrid._cache[p].data[q].hasOwnProperty(r)) {
															c = MapSettings.MapLayers.UTFGrid._cache[p].data[q][r];
															if (!control.labels.labels[c.i]) {
																gridref = q.match(/\((\d+), (\d+)\)/);
																if (gridref) {
																	control.labels.labels[c.i] = [ c.i, c.n, control._map.layerPointToLatLng(tilepos.add(new L.Point(4*gridref[1], 4*gridref[2]))), zoom];
																	control.labels.labels[c.i][4] = new L.GME_identifyLayer(control.labels.labels[c.i][2], (that.parameters.labels === "names") ? {label:c.n, desc:c.i} : {label:c.i, desc:c.n});
																}
															} else {
																if (zoom > control.labels.labels[c.i][3]) {
																	gridref = q.match(/\((\d+), (\d+)\)/);
																	if (gridref) {
																		control.labels.labels[c.i][2] = control._map.layerPointToLatLng(tilepos.add(new L.Point(4*gridref[1], 4*gridref[2])));
																		control.labels.labels[c.i][3] = zoom;
																		control.labels.labels[c.i][4].setPosition(control.labels.labels[c.i][2]);
																	}
																}
															}
															control.labels.labelLayer.addLayer(control.labels.labels[c.i][4]);
														}
													}
												}
											}
										}
									}
								}
							}
						}
						control.labels.updateCachePanel();
						if (control.labels.showLabels) {
							control.labels.clearLabels();
							control.labels.displayLabels();
						}
					},
					removeLabels:function () {
						$("#gme_cachelist").html("");
						control.labels.labelLayer.clearLayers();
						control.labels.labels = {};
					},
					toggleAuto:function () {
						if (control.labels.autoUpdate) {
							control.labels.autoUpdate = false;
							control._map.off("moveend",control.labels.refresh);
							$(".gme-button-labels-auto").removeClass("gme-button-active");
						} else {
							control.labels.autoUpdate = true;
							$(".gme-button-labels-auto").addClass("gme-button-active");
							control._map.on("moveend",control.labels.refresh);
							control.labels.refresh();
						}
					},
					toggleShow:function () {
						if (control.labels.showLabels) {
							control.labels.showLabels = false;
							$(".gme-button-labels-show").removeClass("gme-button-active");
							control.labels.clearLabels();
						} else {
							control.labels.showLabels = true;
							$(".gme-button-labels-show").addClass("gme-button-active");
							control.labels.refresh();
						}
					},
					updateCachePanel:function () {
						var i, j, sortorder =[], html = "";
						for (i in control.labels.labels) {
							if (control.labels.labels.hasOwnProperty(i)) {
								sortorder.push(i);
							}
						}
						sortorder.sort();
						j = sortorder.length;
						for (i =0; i<j; i++){
							html += "<tr><td><a href='https://coord.info/" + sortorder[i] + "' target='_blank' rel='noopener noreferrer'>" + control.labels.labels[sortorder[i]][1] + "</a></td><td class='gme-cache-code'>&nbsp;" + sortorder[i] + "</td><td><a class='gme-event' title='Pan map to cache location' data-gme-action='panTo' data-gme-cache='" + sortorder[i] + "'><img src='../images/silk/map.png' width='16' height='16' alt='Pan' /></a></td></tr>";
						}
						$("#gme_cachelist").html(html);
					}
				};
				$("#searchtabs ul").append("<li id='gme_caches_button'><a href='#gme_caches' title='GME Cache Label List' id='gme_caches_link'>GME</a></li>");
				$("#searchtabs li").css("width", 100/$("#searchtabs li").length+"%");
				$("#pqlink").html("PQs");
				$("#clistButton").html("GCVote");
				document.getElementById("pqlink").innerHTML = "PQs";
				$(div).append("<div id='gme_caches'>\
					<div class='leaflet-control-gme'>\
						<a title='Refresh cache labels' class='gme-event gme-button-refresh-labels gme-button gme-button-l' data-gme-action='refresh'></a><a title='Empty cache list and remove labels from map' class='gme-event gme-button gme-button-clear-labels' data-gme-action='clear'></a><a class='gme-event gme-button gme-button-wide gme-button-labels-show' data-gme-action='show'>Show labels</a><a class='gme-event gme-button gme-button-r gme-button-wide gme-button-labels-auto' data-gme-action='auto'>Auto update</a>\
					</div>\
					<table><tbody id='gme_cachelist'><tr><td colspan='3'>Hit the refresh button above to populate the list.</td></tr></tbody></table></div>");
				$("#gme_caches").css("display","none").on("click", ".gme-event", labelHandler);
				$("#gme-labels-show").on("change", control.labels.toggleShow);
				$("#gme-labels-auto").on("change", control.labels.toggleAuto);
			}
		},
		loadHide: function () {
			function load() {
				window.GME_control = new L.GME_Widget().addTo(map);
				GME_control._layerControl = GME_load_map(map);
				if (gmeConfig.env.dragdrop) {
					map.addControl(new L.GME_dropHandler());
				}
			}
			window.setTimeout(setEnv, 3000);
		},
		loadListing: function () {
			var cache_coords = {},
				mapLink = document.getElementById("ctl00_ContentBody_uxViewLargerMap");
			function load() {
				var parkUrl="", label="", i, parking, uri="&pop=";
				if (L.LatLng.prototype.toUrl === undefined) {
					L.LatLng.prototype.toUrl = function () {var obj=this; if(!(obj instanceof L.LatLng)) {return false;} return [L.Util.formatNum(obj.lat,5),L.Util.formatNum(obj.lng,5)].join(",");};
				}
				$("#map_canvas").replaceWith("<div style=\'width: 325px; height: 325px; position: relative;\' id=\'map_canvas2\'></div>");
				if (gmeConfig.env.dragdrop) {
					$("#cacheDetails .cacheImage").hover(function(e) { $("#cacheDetails .cacheImage").addClass("moveable"); },function(e) { $("#cacheDetails .cacheImage").removeClass("moveable"); });
					$("#cacheDetails .cacheImage").attr("draggable","true").on("dragstart", that.dragStart);
					$("#cacheDetails .cacheImage a").removeAttr("href");
				}
				window.GME_Map = new L.Map("map_canvas2",{center: new L.LatLng(mapLatLng.lat, mapLatLng.lng), zoom:14});
				GME_Map.addControl(new L.control.scale());
				GME_load_map(GME_Map);
				cache_coords = { primary:[mapLatLng], additional:[] };
				if (cmapAdditionalWaypoints && cmapAdditionalWaypoints.length > 0) {
					cache_coords.additional = cmapAdditionalWaypoints;
					if (gmeConfig.env.home) {
						for (i=cmapAdditionalWaypoints.length-1;i>=0;i--){
							if (cmapAdditionalWaypoints[i].hasOwnProperty("editurl")) {
								delete cache_coords.additional[i].editurl;
							}
							parking = cmapAdditionalWaypoints[i];
							if (parking.type === 217 || parking.type === 221) {
								label = parking.type===217?"Parking Area":"Trailhead";
								//parkUrl = `https://www.google.com/maps/dir/${gmeConfig.env.home.toUrl()}/${parking.lat},${parking.lng}/`;
								parkUrl = 'https://www.google.com/maps/dir/${gmeConfig.env.home.toUrl()}/${parking.lat},${parking.lng}/';
								$("#awpt_"+parking.pf)[0].parentNode.parentNode.children[1].innerHTML +=
									'<a target="_blank" rel="noopener noreferrer" href="${parkUrl}"><img width="16" height="16" title="[GME] Directions to ${label}" alt="${label}" src="https://www.geocaching.com/images/icons/16/directions.png" /></a>';
							}
						}
					}
				}
				if (gmeConfig.env.dragdrop) {
					GME_Map.addControl(new L.GME_dropHandler());
				}
				if (cache_coords.primary[0].oldLatLng || cache_coords.primary.length + cache_coords.additional.length > 1) {
					uri += b64encode(JSON.stringify(cache_coords));
					mapLink.href = mapLink.href.replace("http:", "https:") + uri;
					$('#ctl00_ContentBody_MapLinks_MapLinks a[href*="geocaching.com"]').attr("href", function(i, val) {return val + uri;});
				}
				GME_displayPoints(cache_coords, GME_Map, "listing");
			}
			setEnv();
		},
		loadMap: function() {
			function load() {
				function goSearch(e) {
					if (e.type === "click" || (e.which || e.keyCode) === 13) {
						e.preventDefault();
						e.stopImmediatePropagation();
						return GME_control.search($.trim($("#SearchBox_Text").val() || ""));
					}
				}
				var jsonURI;
				GME_load_map(MapSettings.Map);
				if (gmeConfig.env.dragdrop) {
					MapSettings.Map.addControl(new L.GME_dropHandler());
				}
				window.GME_control = GME_load_widget(MapSettings.Map);
				GME_load_labels(GME_control,"#scroller");
				if (gmeConfig.parameters.osgbSearch) {
					$("#SearchBox_OS").on("click keypress", goSearch);
					$(".SearchBox").on("keydown", goSearch);
					$("#search p")[0].innerHTML = "Search by <span style='cursor:help;' title='Enhanced by Geonames'>Address</span>, Coordinates, GC-code,<br/><span style='cursor:help;' title='Jump to a specific zoom level by typing zoom then a number. Zoom 1 shows the whole world, maxiumum zoom is normally 18-22.'>zoom</span> or <span style='cursor:help;' title='To search using a British National Grid reference, just type it in the search box and hit the button! You can use 2, 4, 6, 8 or 10-digit grid refs with the 2-letter prefix but no spaces in the number (e.g. SU12344225) or absolute grid refs with a comma but no prefix (e.g. 439668,1175316).'>Grid Ref</span>";
				}
				if (window.pnlOpen === false) {
					$(".leaflet-control-toolbar,.groundspeak-control-findmylocation,.leaflet-control-scale,.gme-left").css("left","30px");
				}
				if (gmeConfig.env.storage) {
					if (localStorage.GME_cache) {
						try {
							GME_displayPoints(JSON.parse(b64decode(localStorage.GME_cache)), GME_control._map, "clickthru");
							delete localStorage.GME_cache;
						} catch (e) {
							console.error("GME Can't pop cache: " + e);
						}
					}
				}
			}
			setEnv();
		},
		loadSeek: function () {
			function load() {
				function goGR(e) {
					if (e.type === "click" || (e.type === "keypress" && (e.which || e.keyCode) === 13)) {
						e.preventDefault();
						e.stopImmediatePropagation();
						that.seekGR($.trim($("#grRef").val()));
						return false;
					}
				}
				function goCoords(e) {
					var c, coords;
					if (e.type === "click" || (e.type === "keypress" && (e.which || e.keyCode) === 13)) {
						e.preventDefault();
						e.stopImmediatePropagation();
						c=document.getElementById("gme_coords").value;
						if (c) {
							coords = parseCoords(c);
							if (coords) {
								that.seekByLatLng(coords);
								return false;
							}
						}
					}
				}
				function goGoogle(e) {
					var q = document.getElementById("gme_google").value.trim(), url;
					e.preventDefault();
					e.stopImmediatePropagation();
					if (q) {
						url = "https://www.google.co.uk/search?q=allintitle%3A" + encodeURIComponent(q) + "+site%3Awww.geocaching.com%2Fgeocache%2F+OR+site%3Awww.geocaching.com%2Fseek%2Fcache_details.aspx";
						window.open(url, "_blank");
					}
					return false;
				}
				$("#grRef").keypress(goGR);
				$("#grSub").click(goGR);
				$("#gme_coords").keypress(goCoords);
				$("#gme_coords_sub").click(goCoords);
				$("#GME_hereSub").click(that.seekHere);
				$("#GME_googleSub").click(goGoogle);
			}
			setEnv();
		},
		loadType: function () {
			function load() {
				window.GME_control = new L.GME_Widget();
				GME_control._layerControl = GME_get_layerControl();
			}
			function reload() {
				$($(".leaflet-control-layers")[0]).remove();
				try {
					GME_control.removeFrom(map);
				} catch (e) {}
				GME_control.addTo(map);
				GME_control._layerControl.addTo(map);
				if (gmeConfig.env.dragdrop) {
					map.addControl(new L.GME_dropHandler());
				}
                setTimeout(function() {
                    map.eachLayer(function(layer) {
                        if (layer instanceof L.TileLayer) {
                            map.removeLayer(layer);
                        }
                    });
                    GME_control._layerControl.setDefault();
                }, 1000);
			}
			window.setTimeout(setEnv, 3000);
		},
		loadTrack: function () {
			function load() {
				var caches, coords, i, name;
				function getLogPoints (layer) {
					if (layer._latlng && layer._popup && layer._popup._content && ~layer._popup._content.indexOf(name)) {
						coords = layer._latlng;
						$(caches[i].parentNode.parentNode.children[0]).append("<br/><a href='#GME_map_anchor'><img src='https://www.geocaching.com/images/silk/map.png' width='16' height='16' alt='Map' class='gme-action' data-gme-ref='" + coords.lat + "," + coords.lng + "' title='Centre map on this geocache'/></a> #" + layer._icon.innerHTML);
						return;
					}
				}
				GME_load_map(map);
				map.addControl(new L.GME_Widget());
				$("#ctl00_ContentBody_lbHeading").append("<a id=\'GME_map_anchor\'></a>");
				caches = $(".TrackableLogTable a[href*=cache_details]");
				for (i = caches.length - 1; i >= 0; i--) {
					name = caches[i].textContent.trim();
					map.eachLayer(getLogPoints, this);
				}
				$(".TrackableLogTable").on("click", ".gme-action", function(e) { map.panTo(L.latLng(this.getAttribute("data-gme-ref").split(","))); });
			}
			setEnv();
		},
		map: function () {
			var bounds_CI,
				bounds_DE,
				bounds_GB,
				bounds_IE,
				bounds_NI,
				icons = {
					marker: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA8AAAAZCAYAAADuWXTMAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAOQSURBVDiNhdRPSCNXHAfw7xs1mc5MjP9itE5ISjVGQrGxKgu6FIzx1CCskKunsj1YKN68tRdPBQ89hdKLl8JmLRR6sGzAPXRB0VVML2Y3kpDBJkHNv3EmTZjx14tZdM3aHzx4vPf78OP9Hu8xIsJNMABfxuPx7xKJxMT5%2BXn3xcWF0NfXpzscjtL4%2BPjrYDD4I4BXTQAiAhF1xWKxg%2BHhYRoYGCCfz0d%2Bv58CgQD5%2FX7y%2BXw0ODhIY2NjFIvFdonITkRgRMQ2NjZO19fXPxkdHUVPTw8AQFVVqKoKm80Gm80GACgWi0gmk1hbW0uvrq5%2BynZ2dlaWlpZ%2BmpychNVqRalUwv7%2B%2FhUR%2FQPgbwCfMcY%2Bnpqakrq7u1Gv13FwcICtra1v2fLy8sHe3t4XIyMjKBQKdHh4eG4YxhMienc2xthMe3v7bxMTEw6n08lSqRSmp6dfc7lcThZFEYZh4Pj4%2BMowjMe34U1fXhmG8fhmH4IgIJfLyVw%2Bn%2B8SBAGKopBhGDEieoMWQURvDMOIKYpCgiCgUCjYuUKhYBEEAaqq1k3TfNEKNsM0zReqqtZvsJUTBKHRaDSgqqoJ4O1DGMBbVVXNRqMBnucbnNvtzpbLZYii2AZA%2Fh8si6LYVqlU4Ha7FW5oaGi3VqtBkiQrx3GPHpIcxz2SJMlaq9Ugy%2FIu19nZua3rOmRZZhaLZYUx1tcKMsb6LBbLiizLTNd1SJL0J5fJZLaq1eo1Ywxer1fkef4lY2zoPTjE8%2FxLr9crchyHSqVynUwmnzMiwsLCwmE%2Bnw94PB4oikInJye1tra2PzRN%2B0sUxVnTNL%2Fy%2BXwfuVwulslk0N%2FffxyPxz9vBwCXy%2FV9IpH43ePxwOVyMYfDIVxeXkY0TYuIooje3l7wPA8AuLi4QCAQ%2BAEAWPNJut3ufz0ej9Vut3%2BwYdVqFaenp3VFUXgA4Jobs7Ozz3K53IP3lMvlMDMz8%2Fxd95sTSZK%2BKZfLpqZpLaGu6ygWi6bFYnl6D0ejUX1%2Bfv7XbDbbEmezWczNzT3b3NzU7mEAsNlsTyuVinl1dXUHapqGUqlkWq3Wr2%2Bv38HRaFQPh8M%2Fp1KpOziVSiEcDv9yuypwq9u3IxAIlBljdlmWcXZ2huvr68rR0VHX%2B3ncPQkgFAotptNpVKtVpNNphEKhxVZ5zd%2Fz3ohEItsdHR0UiUS2P5TTsjIAOJ3OxWAwmHQ6na2rAvgPIb3JdHxMgbEAAAAASUVORK5CYII%3D',
					tick:'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAXCAYAAAAYyi9XAAAALHRFWHRDcmVhdGlvbiBUaW1lAFRodSAxNyBNYXkgMjAxMiAyMjoxMjo1MiAtMDAwMP%2F5zBkAAAAHdElNRQfcBREVNTVnAq5wAAAACXBIWXMAAAsSAAALEgHS3X78AAAABGdBTUEAALGPC%2FxhBQAAAnRJREFUeNq9lMlrFEEUh19VdU3P1j0koujFmYzE4B8gCaIXTx6SgODFBUTw4lkv4kHxKuLFs4JHEZQkF0GM%2B4KIATHE4DATBMmiSetktq7NVxM7DB4n03nQdHdtv%2FreRmAbrFAo%2BM4e55477Oad7RAkaTKmq%2FqYrMgE3Q464pJL7kGXAQMRu6ClAwEHUodSjlpUzVhdGtElR5IU6QC%2FF2IltHSEkP3%2BOZ833zQFSZKnsRFGdJnxjOPsciD8GoZA4X5shG06Rga9k14inAtxANbkgvwci%2BAm3WiG830c6k%2Fqkqboq0qlUo3FpZ10%2Bo%2BG1kxLgoRJO9dzwn90F%2F2zvsMHuY0d6HXdkEvyWSyClo56tJA9kXUxbtB43tCEk3nTMMt2vmuXIkkaXz4%2BSxgb00nnnfZSbDcDFIHmBywHTqZwjexaEA9m2Ixv6po%2BjkRvi35xAmP1kqTI4TbdeDZp14mSAPldShR%2BHO3tShBvq4peccY0zXm2k42xPDuCBwuMFfPObNBZw2SxrxVs3HNbErSGh9xl%2FWxEr%2BlT%2Fdf6d%2FA8B13Xmu%2Fl7bwwytj4CZqmL0qVUjXa13XSIGWoVtVlY8xscCOwbQsSQwmKbm3Pqx%2FKEiq82GTnvi1lKYoumqq5IMqiGtwOlBFmcy6cbXeXmvqlXvdM0Fr5W%2FkdGLi6%2FmBd1x7VNgZR13YXkiCf8G%2Bxp4LWMFnu0CSdCG4FYbvQA%2BwuH1sS4zgZlUxkrBeCQRCInJt7DxxGxbzIsT7GalO1lvltrgSrwXLnWtILwcgGhgaOYpE%2FpH3Uw5L5olbUMBLWe%2B7SyEzLTOOJ19VP1cLmPf2%2FmLW%2FylgqETpxl%2BsAAAAASUVORK5CYII%3D'
				},
				wptTypes = [[/Geocache/i,"2"],[/Traditional Cache/i,"2"],[/Multi-cache/i,"3"],[/Virtual Cache/i,"4"],[/Letterbox Hybrid/i,"5"],[/Event Cache/i,"6"],[/Unknown cache/i,"8"],[/Webcam Cache/i,"11"],[/Cache In Trash Out Event/i,"13"],[/Wherigo Cache/i,"1858"],[/Locationless \(Reverse\) Cache/i,"12"],[/Mega-Event Cache/i,"453"],[/GPS Adventures Exhibit/i,"1304"],[/Groundspeak Block Party/i,"4738"],[/Groundspeak HQ/i,"3773"],[/Groundspeak Lost and Found Celebration/i,"3774"],[/Lost and Found Event Cache/i,"3653"],[/Project APE Cache/i,"9"],[/Earthcache/i,"137"],[/Question to Answer/i,"218"],[/Parking Area/i,"217"],[/Stages of a Multicache/i,"219"],[/Final Location/i,"220"],[/Trailhead/i,"221"],[/Reference Point/i,"452"]],
				polylineObj = {
					initialize: function (pts, ops) {
						L.Polyline.prototype.initialize.call(this, pts, ops);
						this._length = 0;
						this._markers = L.layerGroup();
						this._updateMarkers();
					},
					addLatLng: function (pt) {
						L.Polyline.prototype.addLatLng.call(this, pt);
						var len = this._latlngs.length;
						this._addMarker(pt, len);
						if (len > 1) {
							this._length += this._latlngs[len-2].distanceTo(this._latlngs[len-1]);
							this.fire("gme-length", {length: this._length});
						}
						return this;
					},
					getData:function() {
						return ((typeof window.btoa === "function") ? "data:application/xml-gpx;base64," : "data:application/xml-gpx,") + b64encode(this.getGPX());
					},
					getGPX: function() {
					var name = $(".CommonUsername").attr("title"),
					author = name ?
					(name + '</name>\r\n\t\t\t<link href="https://www.geocaching.com/profile/?u=' + name + '"><text>' + name + '\'s profile</text></link>\r\n') :
					"Geocaching.com user</name>\r\n",
					date = !!Date.prototype.toISOString ? ["\t\t<time>", new Date().toISOString(), "</time>\r\n"].join("") : "",
					i, l, gpx;
					gpx = ["<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n<gpx creator=\"Geocaching Map Enhancements v", this.getVersion(),
					"\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" version=\"1.1\" xsi:schemaLocation=\"http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd\" xmlns=\"http://www.topografix.com/GPX/1/1\">\r\n\t<metadata>\r\n\t\t<name>GME Export</name>\r\n\t\t<desc>Route file exported from Geocaching.com using Geocaching Map Enhancements.</desc>\r\n\t\t<author>\r\n\t\t\t<name>", author, "\t\t</author>\r\n", date, "\t</metadata>\r\n"].join("");
					// Vytvorenie wypointov (wpt) s popisom (desc)
					for (i = 0, l = this._latlngs.length; i < l; i++) {
					var instructionText = "Instruction for point " + i; // Sem vložte vlastný text inštrukcie podľa potreby
					gpx += [
					"\t<wpt lat=\"", this._latlngs[i].lat, "\" lon=\"", this._latlngs[i].lng, "\">\r\n",
					"\t\t<name>P", i, "</name>\r\n",
					"\t\t<desc>", instructionText, "</desc>\r\n",
					"\t\t<type>Waypoint</type>\r\n",
					"\t</wpt>\r\n"
					].join("");
					}		
					// Route (rte) ostáva zachovaná
					gpx += "\t<rte>\r\n\t\t<name>GME exported route</name>\r\n\t\t<src>Manual entry</src>\r\n\t\t<number>1</number>\r\n";
					for (i = 0, l = this._latlngs.length; i < l; i++) {
					gpx += [
					"\t\t<rtept lat=\"", this._latlngs[i].lat, "\" lon=\"", this._latlngs[i].lng, "\">\r\n",
					"\t\t\t<name>P", i, "</name>\r\n",
					"\t\t\t<type>Waypoint</type>\r\n",
					"\t\t</rtept>\r\n"
					].join("");
					}
					gpx += "\t</rte>\r\n</gpx>";
					return gpx;
					},
					getLength: function() {
						return this._length;
					},
					onAdd: function(map) {
						map.addLayer(this._markers);
						this._markers.eachLayer(function(a) {a.dragging.enable();});
						return L.Polyline.prototype.onAdd.call(this, map);
					},
					onRemove: function(map) {
						map.removeLayer(this._markers);
						return L.Polyline.prototype.onRemove.call(this, map);
					},
					removePt: function(num) {
						this.spliceLatLngs(num-1,1);
						this._updateMarkers();
					},
					setLatLngs: function(pts) {
						L.Polyline.prototype.setLatLngs.call(this, pts);
						this._updateMarkers();
						return this;
					},
					_addMarker: function(pt, num) {
						var mark = new L.Marker(pt, {
							icon: new L.Icon({draggable: "true", iconUrl: icons.marker, iconSize: new L.Point(15, 25), iconAnchor: new L.Point(8,25)}),
							zIndexOffset:99, title: "Route Point #"+num
						});
						mark._routeNum = num;
						mark.bindPopup(["<p><strong>Route Point #", num, "</strong><br/>Centre: ",pt.toUrl(),"<br/><strong>",DMM(pt),"</strong><br/><span style='float:right;'><a class='gme-event' data-gme-action='removeDistMarker' data-gme-layer='", this._leaflet_id, "' data-gme-ref='",num,"'>Clear</a>, <a class='gme-event' data-gme-layer='", this._leaflet_id, "' data-gme-action='clearDist'>Clear All</a>, <a class='gme-event gme-draggable-gpx' data-gme-action='exportDist' data-gme-layer='", this._leaflet_id, "' draggable='true'>GPX</a>, <a class='gme-event gme-draggable-createtrace' data-gme-action='exportDist' data-gme-layer='", this._leaflet_id, "' draggable='true'>Find route</a></span></p>"].join(""));
						mark.on("dragend", this._moveMarker, this);
						this._markers.addLayer(mark);
						if (mark.dragging) {
							mark.dragging.enable();
						}
					},
					_moveMarker: function(e) {
						this.spliceLatLngs(e.target._routeNum - 1, 1, e.target.getLatLng());
						this._updateLength();
					},
					_updateLength: function() {
						var i;
						this._length = 0;
						for (i=1; i< this._latlngs.length; i++) {
							this._length += this._latlngs[i-1].distanceTo(this._latlngs[i]);
						}
						this.fire("gme-length", {length: this._length});
						return this._length;
					},
					_updateMarkers: function() {
						var i;
						this._markers.clearLayers();
						if (this._latlngs.length > 0) {
							this._addMarker(this._latlngs[0],1);
							for (i=1; i< this._latlngs.length; i++) {
								this._addMarker(this._latlngs[i], i+1);
							}
						}
						this._updateLength();
					}
				},
				quadkeyLayerObj = {
					tile2quad: function(x, y, z) {
						var i, digit, mask, quad = "";
						for (i = z; i > 0; i--) {
							digit = 0;
							mask = 1 << (i - 1);
							if ((x & mask) !== 0) { digit += 1; }
							if ((y & mask) !== 0) { digit += 2; }
							quad = quad + digit;
						}
						return quad;
					},
					getTileUrl: function(tilePoint) {
						return L.Util.template(this._url, L.extend({
							s: this._getSubdomain(tilePoint),
							q: this.tile2quad(tilePoint.x, tilePoint.y, this._getZoomForUrl()),
							z: this._getZoomForUrl()
						}, this.options));
					}
				},
				complexLayerObj = {
					getTileUrl: function(tilePoint) {
						return L.Util.template(this._url, L.extend({
							s4: tilePoint.x%4 + 4*(tilePoint.y%4),
							x100: this._getZoomForUrl()<=13?"":Math.floor(tilePoint.x/100)+"/",
							z: this._getZoomForUrl(),
							x: tilePoint.x,
							y: tilePoint.y
						}, this.options));
					}
				};
				
			window.GME_displayPoints = function GME_displayPoints(plist, map, context) {
				var bounds = new L.LatLngBounds(), i, p, layers = L.featureGroup(), ll, op, PinIcon = L.Icon.extend({iconSize: new L.Point(20, 23),iconAnchor: new L.Point(10,23)});
				function checkType(t) {
					var j;
					for (j = wptTypes.length-1; j>=0; j--) {
						if (t==wptTypes[j][1]) {
							return wptTypes[j][1];
						}
					}
					return 452;
				}
				for (i=plist.primary.length-1; i>= 0; i--) {
					p = plist.primary[i];
					ll = L.latLng(p.lat, p.lng);
					if (context === "listing" || context === "dragdrop" || p.isUserDefined){
						layers.addLayer(L.marker(ll, {icon: new PinIcon({iconUrl:"/images/wpttypes/pins/" + checkType(p.type) + ".png",iconAnchor: L.point(10,23)}),clickable: false, zIndexOffset:98, title: p.name + (p.isUserDefined?" (Corrected coordinates)":"")}));
						if (p.isUserDefined) {
							layers.addLayer(L.marker(ll, {icon: new PinIcon({iconSize: new L.Point(28,23), iconAnchor: L.point(10,23), iconUrl:icons.tick}),clickable: false, zIndexOffset:99, title: p.name + " (Corrected coordinates)"}));
						}
					} else {
						bounds.extend(ll);
					}
					if (p.isUserDefined) {
						op = L.latLng(p.oldLatLng[0], p.oldLatLng[1]);
						layers.addLayer(L.polyline([op, ll], { clickable:false, weight:3 }));
						if (context === "listing") {
							layers.addLayer(L.circleMarker(op, {clickable:false, weight:3, radius:6}));
						}
					}
				}
				if (!window.moziGoMarkers) window.moziGoMarkers = [];
				for (i = plist.additional.length - 1; i >= 0; i--) {
				p = plist.additional[i];
				ll = L.latLng(p.lat, p.lng);
				var marker = L.marker(ll, {
				icon: L.icon({
				iconUrl: "https://maps.google.com/mapfiles/ms/icons/ltblue-dot.png",
				iconSize: [16, 16],
				iconAnchor: [8, 8]
				}),
				title: p.name,
				clickable: false
				});
				layers.addLayer(marker);
				window.moziGoMarkers.push(marker); // 🔸 uloženie
				}
				
				if (plist.routes) {
//	debugger;
				for (i = plist.routes.length - 1; i >= 0; i--) {
				var route = plist.routes[i];
				var poly = L.polyline(route.points, {
					color: route.color,
					dashArray: route.dash,
					weight:route.weight
				});
				var startPoint = getLastPoint(route.points);
				var startMarker = L.marker(startPoint, {
					icon: L.icon({
					iconUrl: "https://maps.google.com/mapfiles/ms/icons/green-dot.png",
					iconSize: [20, 20],
					iconAnchor: [10, 20]
				}),
				title: "Začiatok trasy"
				}).addTo(MapSettings.Map);
				console.log("✅ Created startMarker for", route.name);
				poly._gpxinfo = route;

				var name = route.name || "Trasa " + (i + 1);
				layers.addLayer(poly);
				var lid = "poly_" + poly._leaflet_id;
				if (!window.moziGoRoutes) window.moziGoRoutes = {};
				window.moziGoRoutes[lid] = poly;
				if (typeof startMarker !== "undefined") {
				poly._startmarker = startMarker;
				var layerId = "poly_" + poly._leaflet_id;
				window.moziGoRoutes[layerId] = poly;
				console.log("🟢 Assigned startMarker to", lid);
				} else {
				console.log("⚠️ No startMarker available for", lid);
				}
				var id = poly._leaflet_id;
				window["poly_" + id] = poly;
				poly._additionalMarkers = window.moziGoMarkers.slice();
				debugger;
				var popupContent = "<b>" + name + "</b><br>";

				// pridaj len ak je farba trasy modrá
				if (route.color === "#0000FF") {
				popupContent += "<a href='delphiapp://showroute?file=\"" + poly._gpxinfo.filename +
                "\"&layerid=" + layerId + "'>📌 Look for caches around this route 📌️</a><br>";
				
				}
				popupContent +=
				"<a href='#' onclick='removeMoziGoLayer(\"" + layerId + "\"); return false;'><span style='font-size:16px'> ❌ </span>Delete track</a><br>" +
				"<a href='#' onclick='deleteAllPolylines(); return false;'><span style='font-size:16px'> 🗑️ </span> Delete all tracks</a><br>" +
				"<a href='#' onclick='clickOnInfo(" + id + "); return false;'><span style='font-size:16px'> ℹ️ </span>Show info</a>";
				// pripoj popup k polyline
				poly.bindPopup(popupContent);
				
				
				
				}
			}
			bounds.extend(layers.getBounds());
			if (bounds.isValid()) {
				switch (context) {
				case "listing":
					map.fitBounds(bounds, {padding:[10, 10], maxZoom: 15});
					break;
				case "clickthru":
					if (map.getBoundsZoom(bounds) > 15) {
					map.panTo(bounds.getCenter()).setZoom(15);
					} else {
							map.fitBounds(bounds);
					}
					break;
					default:
					map.panTo(bounds.getCenter());
					}
				}
				map.addLayer(layers);
				return bounds;
			}
			function genericLayerFn(url, options) {
                function filterOpts(opts) {
                    // Remove GME's internal options, so they don't get passed to servers (WMS in particular). 
                    var opt, filtered = {}, exclude = ["tileUrl", "ignore", "alt"];
                    for (opt in opts) {
                        if (exclude.indexOf(opt) === -1) {
                            filtered[opt] = options[opt];
                        }
                    }
                    return filtered;
                }
                var filteredOpts = filterOpts(options);
                
				if (typeof url === "string") {
					return (/\{q\}/).test(url)?(new L.GME_QuadkeyLayer(url, filteredOpts)):((/\{s4\}|\{x100\}/).test(url)?(new L.GME_complexLayer(url,filteredOpts)):((/\{x\}/).test(url)?(new L.TileLayer(url, filteredOpts)):(new L.TileLayer.WMS(url, filteredOpts))));
				}
				console.error("GME: Bad map source: " + JSON.stringify(options));
				return undefined;
			}
			function setBrightness(e) {
				var brightness=this.brightness||that.parameters.brightness;
				if (brightness<1) {
					$(".leaflet-container").css("backgroundColor","#000");
				} else {
					$(".leaflet-container").css("backgroundColor","#ddd");
				}
				if (e.layer._url && /^http/.test(e.layer._url) && e.layer.options && !e.layer.options.overlay) {
					e.layer.setOpacity(brightness);
				}
			}
			function switchLayer(e) {
				var layer = e.layer;
				if (layer.options && layer.options.tileUrl && !layer.options.overlay) {
					this.layersMaxZoom = layer.options.maxZoom;
					this.layersMinZoom = layer.options.minZoom;
					if (isNaN(layer.options.maxZoom) || !isNaN(layer.options.minZoom)) {
						this._zoomBoundLayers[L.stamp(layer)] = layer;
						this._updateZoomLevels();
					}
					if (this.getZoom() > this.layersMaxZoom) { this.setZoom(this.layersMaxZoom); }
					if (this.getZoom() < this.layersMinZoom) { this.setZoom(this.layersMinZoom); }
					this.brightness = e.layer.options.brightness||that.parameters.brightness;
				}
			}
			
			function GME_get_layerControl(map){
				var maps = {}, overlays = {}, allMaps = that.parameters.maps, apiKeys = that.parameters.apiKeys,baseMaps, control, i, layer, src;
					for (baseMaps = 0, i = 0; i < allMaps.length; i++) {
						src = allMaps[i];
						if (!src.ignore) {
							let tileUrl = src.tileUrl;
							if (apiKeys && src.apiKey && src.apiKeyQuery) {
								const apiKey = apiKeys[src.apiKey];
								if (apiKey) {
//									console.log("apiKey="+apiKey);
									var replacedTemplate = src.apiKeyQuery.replace(/\{apikey\}/, apiKey);
//									console.log("replacedTemplate="+replacedTemplate);
//									debugger;
//									const url = new URL(tileUrl);
									const url={};
									url.href= "https://tile.thunderforest.com/cycle/%7Bz%7D/%7Bx%7D/%7By%7D.png?apikey="+apiKey;
									url.origin= "https://tile.thunderforest.com";
									url.protocol= "https:"
									url.username= "";
									url.password= "";
									url.host= "tile.thunderforest.com";
									url.hostname= "tile.thunderforest.com";
									url.port= "";
									url.pathname= "/cycle/%7Bz%7D/%7Bx%7D/%7By%7D.png";
									url.search= "";
//									console.table(url); nefunguje v IE
									const search = url.search;
									url.search = search ? '${search}&${replacedTemplate}' : '?${replacedTemplate}';
									tileUrl = decodeURI(url.href);
								}
							}

							layer = L.GME_genericLayer(tileUrl, src);
							if (layer) {
								if (src.overlay) {
									overlays[src.alt] = layer;
									if (src.alt === that.parameters.defaultHillShade) {
										layer.default = true;
									}
								} else {
									if (src.alt === that.parameters.defaultMap) {
										layer.default = true;
									}
									maps[src.alt] = layer;
									baseMaps++;
								}
							}
						}
					}
					if (baseMaps > 0) {
						// Only return a new control if we have some basemaps.
						control = L.control.layers(maps, overlays);
						control.setDefault = function () {
							var defLayer, defOverlay, j;
							for (j in this._layers) {
								if (this._layers.hasOwnProperty(j)
									&& this._layers[j].layer.default) {
									if (!this._layers[j].overlay) {
										defLayer = j;
									} else {
										defOverlay = j;
									}
								}
							}
							if (!defLayer) {
								defLayer = Object.keys(this._layers)[0];
							}
							if (this._map && defLayer !== undefined) {
								this._map.addLayer(this._layers[defLayer].layer, true);
							}
							if (this._map && defOverlay !== undefined) {
								this._map.addLayer(this._layers[defOverlay].layer, true);
							}
							return defLayer;
						};
					}
					return control;
			}
			function GME_load_map(map){
				var control = GME_get_layerControl(),
					layer;

				map.on("layeradd", switchLayer);
				if (document.createElement("div").style.opacity!==undefined) {
					map.on("layeradd", setBrightness);
				}

				// If we're adding our own map selector control, we need to manually remove any pre-existing map layers.  Otherwise, they persist in the background underneath
				// * the layers provided by GME.	We check for the _url or _google attribute to distinguish map layers from other Leaflet layers like controls or popups 
				if (control) {
					if (gmeConfig.env.page === "maps" || gmeConfig.env.page === "track" || gmeConfig.env.page === "hide" || gmeConfig.env.page === "hide") {
						$($(".leaflet-control-layers")[0]).remove();
						for (layer in map._layers) {
							if (map._layers[layer] instanceof L.TileLayer) {
                                if (window.MapSettings !== undefined && MapSettings.MapLayers !== undefined && MapSettings.MapLayers.Geocache === map._layers[layer]) {
                                    // Leave geocache layer in place
                                } else {
                                    map.removeLayer(map._layers[layer]);
                                }
							}
						}
					}
					map.addControl(control);
					control.setDefault();
				}
			}
		},
		osgb: function () {
			function OSGridToLatLng(E,N) {
				var a = 6377563.396,
					b = 6356256.910,
					F0 = 0.9996012717,
					lat0 = 49*Math.PI/180,
					lon0 = -2*Math.PI/180,
					N0 = -100000,
					E0 = 400000,
					e2 = 1 - (b*b)/(a*a),
					n = (a-b)/(a+b),
					n2 = n * n,
					n3 = n * n2,
					lat = lat0,
					lon,
					M = 0,
					Ma, Mb, Mc, Md, cosLat, sinLat, nu, nu3, nu5, nu7, rho, eta2, tanLat, tan2lat, tan4lat, tan6lat, secLat, VII, VIII, IX, X, XI, XII, XIIA, dE, dE2, dE3, dE4, dE5, dE6, dE7, tx, ty, tz, rx, ry, rz, s1, sinPhi, cosPhi, sinLambda, cosLambda, eSq, nu2, x1, y1, z1, x2, y2, z2, p, phi, phiP, precision, lambda;
				do {
					lat = (N-N0-M)/(a*F0) + lat;
					Ma = (1 + n + (5/4)*n2 + (5/4)*n3) * (lat-lat0);
					Mb = (3*n + 3*n*n + (21/8)*n3) * Math.sin(lat-lat0) * Math.cos(lat+lat0);
					Mc = ((15/8)*n2 + (15/8)*n3) * Math.sin(2*(lat-lat0)) * Math.cos(2*(lat+lat0));
					Md = (35/24)*n3 * Math.sin(3*(lat-lat0)) * Math.cos(3*(lat+lat0));
					M = b * F0 * (Ma - Mb + Mc - Md);
				} while (N-N0-M >= 0.01);
				cosLat = Math.cos(lat);
				sinLat = Math.sin(lat);
				nu = a*F0/Math.sqrt(1-e2*sinLat*sinLat);
				rho = a*F0*(1-e2)/Math.pow(1-e2*sinLat*sinLat, 1.5);
				eta2 = nu/rho-1;
				tanLat = Math.tan(lat);
				tan2lat = tanLat*tanLat;
				tan4lat = tan2lat*tan2lat;
				tan6lat = tan4lat*tan2lat;
				secLat = 1/cosLat;
				nu3 = nu*nu*nu;
				nu5 = nu3*nu*nu;
				nu7 = nu5*nu*nu;
				VII = tanLat/(2*rho*nu);
				VIII = tanLat/(24*rho*nu3)*(5+3*tan2lat+eta2-9*tan2lat*eta2);
				IX = tanLat/(720*rho*nu5)*(61+90*tan2lat+45*tan4lat);
				X = secLat/nu;
				XI = secLat/(6*nu3)*(nu/rho+2*tan2lat);
				XII = secLat/(120*nu5)*(5+28*tan2lat+24*tan4lat);
				XIIA = secLat/(5040*nu7)*(61+662*tan2lat+1320*tan4lat+720*tan6lat);
				dE = (E-E0);
				dE2 = dE*dE;
				dE3 = dE2*dE;
				dE4 = dE2*dE2;
				dE5 = dE3*dE2;
				dE6 = dE4*dE2;
				dE7 = dE5*dE2;
				lat = lat - VII*dE2 + VIII*dE4 - IX*dE6;
				lon = lon0 + X*dE - XI*dE3 + XII*dE5 - XIIA*dE7;
				tx=446.448;
				ty=-125.157;
				tz=542.060;
				rx=7.2819014902652306237205098174164e-7;
				ry=1.1974897923405539041670878328241e-6;
				rz=4.0826160086234026020206666559563e-6;
				s1=0.9999795106;
				sinPhi = Math.sin(lat);
				cosPhi = Math.cos(lat);
				sinLambda = Math.sin(lon);
				cosLambda = Math.cos(lon);
				eSq = (a*a - b*b) / (a*a);
				nu2 = a / Math.sqrt(1 - eSq*sinPhi*sinPhi);
				x1 = nu2 * cosPhi * cosLambda;
				y1 = nu2 * cosPhi * sinLambda;
				z1 = (1-eSq)*nu2 * sinPhi;
				x2 = tx + x1*s1 - y1*rz + z1*ry;
				y2 = ty + x1*rz + y1*s1 - z1*rx;
				z2 = tz - x1*ry + y1*rx + z1*s1;
				a = 6378137;
				b = 6356752.3142;
				eSq = (a*a - b*b) / (a*a);
				p = Math.sqrt(x2*x2 + y2*y2);
				phi = Math.atan2(z2, p*(1-eSq));
				phiP = 2*Math.PI;
				precision = 4 / a;
				while (Math.abs(phi-phiP) > precision) {
					nu = a / Math.sqrt(1 - eSq*Math.sin(phi)*Math.sin(phi));
					phiP = phi;
					phi = Math.atan2(z2 + eSq*nu*Math.sin(phi), p);
				}
				lambda = Math.atan2(y2, x2);
				return {lat: phi*180/Math.PI, lng:lambda*180/Math.PI};
			}
			function gridrefLetToNum(letters, numbers) {
				letters = letters.toUpperCase();
				var e, n,
					l1 = letters.charCodeAt(0) - "A".charCodeAt(0),
					l2 = letters.charCodeAt(1) - "A".charCodeAt(0);
				if (l1 > 7) { l1--; }
				if (l2 > 7) { l2--; }
				e = ((l1-2)%5)*5 + (l2%5);
				n = (19-Math.floor(l1/5)*5) - Math.floor(l2/5);
				e += numbers.slice(0, numbers.length/2);
				n += numbers.slice(numbers.length/2);
				switch (numbers.length) {
					case 2: e += "5000"; n += "5000"; break;
					case 4: e += "500"; n += "500"; break;
					case 6: e += "50"; n += "50"; break;
					case 8: e += "5"; n += "5"; break;
				}
				return [e, n];
			}
			function parseGR(searchVal) {
				var ngr, gr = searchVal.match(/^\s*([hnstHNST][A-Ha-hJ-Zj-z])\s*((?:\d\d){1,5})\s*$/);
				if (gr) {
					if (gr.length===3){
						if (2* Math.floor(gr[2].length / 2) === gr[2].length){
							ngr = gridrefLetToNum(gr[1], gr[2]);
							return OSGridToLatLng(ngr[0], ngr[1]);
						}
					}
					return null;
				}
				gr = searchVal.match(/^\s*(\d{3,6})\s*,\s*(\d{4,7})\s*$/);
				if (gr) {
					if (gr.length===3){
						return OSGridToLatLng(gr[1], gr[2]);
					}
				}
				return null;
			}
		},
		seek: function () {
			this.seekGR = function(searchVal) {
				if (searchVal.length > 0) {
					var coords = parseGR(searchVal);
					if (coords !== null) {
						that.seekByLatLng(coords);
					} else {
						alert("Could not recognise grid reference.");
					}
				}
			};
		},
		widget: function () {
			var locationControlObj = {
				onAdd:function(map){
					var el, tracking=false, container=L.DomUtil.create("div", "leaflet-control-toolbar groundspeak-control-findmylocation gme-left");
					function located(l){
						this.panTo(l.latlng);
					}
					function click(e){
						L.DomEvent.stopPropagation(e);
						if (tracking) {
							map.stopLocate();
							map.off("locationfound",located);
							tracking = false;
							$(".groundspeak-control-findmylocation-lnk").removeClass("gme-button-active");
							$("#GME_loc").attr("title","Follow My Location");
						} else {
							map.on("locationfound",located);
							map.locate({enableHighAccuracy:true,watch:true,timeout:60000});
							tracking = true;
							$(".groundspeak-control-findmylocation-lnk").addClass("gme-button-active");
							$("#GME_loc").attr("title","Stop following");
						}
					}
					function click_once(e) {
						L.DomEvent.stopPropagation(e);
						this.locate({setView:true, maxZoom:this.getZoom(), minZoom:this.getZoom(), enableHighAccuracy:true, timeout:60000});
					}
					el = document.createElement("a");
					el.id="GME_loc";
					el.title=that.parameters.follow?"Follow My Location":"Find My Location";
					el.className="groundspeak-control-findmylocation-lnk";
					if (that.parameters.follow) {
						L.DomEvent.addListener(el,"click",click,map);
					} else {
						L.DomEvent.addListener(el,"click",click_once,map);
					}
					container.appendChild(el);
					return container;
				}
			},
			widgetControlObj = {
				options:{position:"bottomleft"},
				onAdd:function(contextmap){
					var elem, container=L.DomUtil.create("div","leaflet-control-gme"), control=this, html="";
					function onPopup(e) {
						if (e.layer._container && /leaflet-popup/.test(e.layer._container.className)) {
							$(e.layer._contentNode).on("click", ".gme-event", contextmap, mapHandler);
							$(e.layer._contentNode).on("dragstart", ".gme-draggable-gpx", {line: control._dist_line}, dragGPXHandler);
						}
					}
					function offPopup(e) {
						if (e.layer._container && /leaflet-popup/.test(e.layer._container.className)) {
							$(e.layer._contentNode).off("click", ".gme-event", contextmap, mapHandler);
							$(e.layer._contentNode).off("dragstart", ".gme-draggable-gpx", {line: control._dist_line}, dragGPXHandler);
						}
					}
					function mapHandler(e) {
						var action = this.getAttribute("data-gme-action"),
							c1 = this.getAttribute("data-gme-coords"),
							c2, coords,
							data = this.getAttribute("data-gme-ref"),
							layer = this.getAttribute("data-gme-layer");
						e.stopPropagation();
						if (action !== "exportDist") {
							e.preventDefault(e);
						}
						if (c1) {
							c2 = c1.match(/(-?\d{1,2}(\.\d+)?),(-?\d{1,3}(\.\d+)?)/);
							if (c2 && c2.length === 5 && validCoords(c2[1], c2[3])) {
								coords = new L.LatLng(c2[1], c2[3]);
							}
						}
						if (action === "clearDist") { control.clearDist(); }
						if (action === "clearMarkers") { control.clearMarkers(); }
						if (action === "dropDist" && coords) { control.dropDist(coords); }
						if (action === "dropMarker" && coords) { control.dropMarker(coords); }
						if (action === "exportDist") { control.exportDist(this); }
						if (action === "getGeograph" && coords) { that.getGeograph(coords); }
						if (action === "getHeight" && coords) { that.getHeight(coords); }
						if (action === "getPostcode" && coords) { control.getPostcode(coords); }
						if (action === "panTo" && coords) { e.data.panTo(coords); }
						if (action === "removeMarker" && data) { control.removeMarker(data); }
						if (action === "removeDistMarker" && data) { control.removeDistMarker(data); }
						if (action === "toggleCaches") { control.toggleCaches(); }
						if (action === "toggleWpts") { control.toggleWpts(); }
						$(".leaflet-popup-close-button").each(function() {this.click();});
					}
					function dragGPXHandler(e) {
						e.originalEvent.dataTransfer.effectAllowed = "copy";
						var plain = e.data.line.getGPX(), data = e.data.line.getData();
						e.originalEvent.dataTransfer.setData("application/xml-gpx", plain);
						e.originalEvent.dataTransfer.setData("text/uri-list", data);
						e.originalEvent.dataTransfer.setData("DownloadURL", "application/xml-gpx:gme-export.gpx:" + data);
						e.originalEvent.dataTransfer.setData("text/plain", plain);
					}
					function widgetHandler(e) {
						var action = this.getAttribute("data-gme-action");
						e.stopPropagation();
						if (action === "panToHome") { control.panToHome(); }
						if (action === "toggleInfo") { control.toggleTool("info"); }
						if (action === "toggleRoute") { control.toggleTool("route"); }
						if (action === "toggleCaches") { control.toggleCaches(); }
						if (action === "toggleWpts") { control.toggleWpts(); }
					}
					this._map = contextmap;
					this._map.infoMode = false;
					this._map.routeMode = false;
					this._markers = L.layerGroup().addTo(contextmap);
					html = "<button type='button' class=\'GME_info gme-button gme-button-l\' title=\'Enable location info tool\' data-gme-action=\'toggleInfo\'></button>";
					html += "<button type='button' class=\'GME_hide gme-button\' title=\'Hide caches\' data-gme-action=\'toggleCaches\'></button>";
					html += "<button type='button' class=\'GME_route gme-button\' title=\'Enable route tool\' data-gme-action=\'toggleRoute\'></button>";
					if (gmeConfig.env.home) {
						html += "<button type='button' title=\'Go to home location\' class=\'GME_home gme-button\' data-gme-action=\'panToHome\'></button>";
					}
					if (gmeConfig.parameters.osgbSearch) {
						$(".GME_search_results").on("click", ".gme-event", contextmap, mapHandler);
					}
					if (gmeConfig.env.storage) {
						html += "<a class=\'GME_config gme-button\' title=\'Configure Geocaching Map Enhancements\' href=\'#GME_config\'></a>";
					}
					html += "<button type='button' class=\'GME_wpthide gme-button\' title=\'Hide wpts\' data-gme-action=\'toggleWpts\'></button>";					
					container.innerHTML = html;
					$(container.lastChild).addClass("gme-button-r");
					container.innerHTML += "<span class=\'gme-button gme-button-l gme-button-r gme-scale-container\' title=\'Approximate width of the full map view\' style=\'cursor:help;\'>Width: <span class=\'gme-scale\'>-</span></span><span class=\'gme-distance-container gme-button gme-button-r\' title=\'Measured distance\'>Route: <span class=\'gme-distance\'>"+ formatDistance(0) +"</span></span>";
					contextmap.addControl(new L.GME_ZoomWarning()).on("layeradd", onPopup).on("layerremove", offPopup).on("viewreset", this.updateScale, this);
					$(container).on("click", ".gme-button", this, widgetHandler);
					$(window).on("resize", this, (function (context) { var t = {timer: null}; return function () { context.updateScale(context._map, t);}; } (this)));
					return container;
				},
				clearDist:function () {
					this._dist_line.off("gme-length");
					this._map.removeLayer(this._dist_line);
					delete this._dist_line;
					$(".gme-distance-container").removeClass("show");
					$(".gme-distance").html(formatDistance(0));
					$(".gme-scale-container").addClass("gme-button-r");
				},
				clearMarkers:function () {
					this._markers.clearLayers();
				},
				dropDist:function(ll) {
					if (!validCoords(ll)) { return; }
					var dist, formatted;
					if (this._dist_line === undefined) {
						this._dist_line = new L.GME_DistLine([ll], {clickable:false});
						this._dist_line.on("gme-length", function (e) {var b1=new LatLon(this._latlngs[this._latlngs.length-2].lat,this._latlngs[this._latlngs.length-2].lng);var b2=new LatLon(this._latlngs[this._latlngs.length-1].lat,this._latlngs[this._latlngs.length-1].lng); $(this._map._container).find(".gme-distance").html(formatDistance(e.length)+" Last dist/bear:"+formatDistance(b1.distanceTo(b2)*1000)+"/"+b1.bearingTo(b2).toFixed(2)+"°")});
						this._map.addLayer(this._dist_line);
						$(this._map._container).find(".gme-distance-container").addClass("show");
						$(this._map._container).find(".gme-scale-container").removeClass("gme-button-r");
					} else {
						this._dist_line.addLatLng(ll);
					}
				},
				exportDist:function(e) {
					if (!this._dist_line) { return; }
					e.download = "ExportedRoute.gpx";
					e.href = "data:application/xml-gpx," + encodeURIComponent(this._dist_line.getGPX());
					return false;
				},
				dropMarker:function(ll, rad) {
					if (!validCoords(ll)) { return; }
					var circle,
						defaultRadius = 0.161,
						group,
						label = "Marker",
						m = 1000,
						r, radius, raw,
						unit = "km";
					if (that.parameters.measure !== "metric") {
						unit = "miles";
						defaultRadius = 0.1;
						m = 1609.344;
					}
					radius = defaultRadius;
					if (!isNaN(rad)) {
						radius = rad * 1;
					} else {
						raw = window.prompt("Radius in " + unit + " [, label]", defaultRadius).match(/([\d]*\.?[\d]*)\s*,?\s*(.*)/);
						if (raw) {
							if (raw.length === 3) {
								radius = raw[1] * 1;
								label = raw[2] || label;
							} else {
								label = raw;
							}
						}
					}
					if (radius) {
						radius *= m;
						if (isNaN(radius)) { radius = 161; }
					} else {
						radius = 161;
					}
					circle = new L.Circle(ll, radius, {weight:2});
					group = new L.LayerGroup([circle, new L.CircleMarker(ll, {weight:2, radius:3})]);
					this._markers.addLayer(group);
					r = (radius / m).toFixed(3) + " " + unit;
					circle.bindPopup("<p><strong>" + label + "</strong><br/>Radius: " + r + "<br/>Centre: decimal " + ll.toUrl() + "<br/><strong>" + DMM(ll) + "</strong><br/><span style='float:right;'><a class='gme-event' data-mz='" + ll+':'+ radius + "'>Download Caches</a>, <a class='gme-event' data-gme-action='removeMarker' data-gme-ref='" + group._leaflet_id + "'>Clear</a>, <a class='gme-event' data-gme-action='clearMarkers'>Clear All</a></span></p>");
				},
				getPostcode:function(coords) {
					var that = this, callprefix="GME_postcode_callback",call;
					function makeCallback(callname) { callbackCount++; return function (json) {
						var m;
						if (json !== undefined && json.status === 200) {
							if (json.result && json.result.length > 0) {
								m = "<p>" + json.result[0].postcode + (json.result[0].parish ? (", " + json.result[0].parish) :	 "") + (json.result[0].admin_ward ? (", " + json.result[0].admin_ward) :	"") + "</p>";
							} else {
								m = "<p>No postcode found for this location.<br />Is it within 500m of an occupied building?</p>";
							}
						} else {
							m = "<p>Error fetching data from postcodes.io</p>";
						}
						if (json.result && !isNaN(json.result[0].latitude) && !isNaN(json.result[0].longitude)) {
							L.popup().setLatLng({lat: json.result[0].latitude, lng: json.result[0].longitude}).setContent(m).openOn(that._map);
						} else {
							$.fancybox(m);
						}
						$("#"+callname).remove();
						if (window[callname] !== undefined) { delete window[callname]; }
					};}
					if (validCoords(coords)) {
						call = callprefix + callbackCount;
						window[call] = makeCallback(call);
						JSONP("https://api.postcodes.io/postcodes/lon/" + coords.lng + "/lat/" + coords.lat + "?radius=500&limit=1&callback=" + call, call);
					} else {
						console.error("GME: Bad coordinates to getPostcode");
					}
				},
				panToHome:function () {
					if (gmeConfig.env.home) {
						this._map.panTo(gmeConfig.env.home);
						return true;
					}
					return false;
				},
				removeDistMarker:function(mark){
					if (this._dist_line) {
						this._dist_line.removePt(mark);
						$(this._map._container).find(".gme-distance").html(formatDistance(this._dist_line.getLength()));
					}
				},
				removeMarker:function(mark){
					this._markers.removeLayer(this._markers._layers[mark]);
				},
				removeMarkers:function(mark){
					this._markers.clearLayer(this._markers._layers[mark]);
				},
				showInfo:function (e) {
					var control=this, popupContent="<p>", popup = new L.Popup(), i;

					for(i = 0; i < this.tools.length; i++) {
                        if( this.tools[i].isValid(e.latlng, control._map.getZoom())) {
                            popupContent += this.tools[i].getHTML(e.latlng, control._map.getZoom(), control._map) + " ";
                        }
					}
					popupContent += "</p>";
						
					popup.setLatLng(e.latlng);
					popup.setContent(popupContent);
					control._map.addLayer(popup);
				},
                tools: [
                    {
                        name: "Coords",
                        getHTML: function(coords, zoom, map) {
                            var ll = coords.toUrl();
                            return "<strong>" + DMM(coords) + "</strong><br/>Dec: <a href='geo:" + ll + "?z=" + zoom + "'>" + ll + "</a></br>";
                        },
                        isValid: function(coords, zoom) { return true; }
                    },
                    {
                        name: "List caches",
                        getHTML: function(coords, zoom, map) {
                            return "<a title='List " + (that.parameters.filterFinds ? "unfound " : "") + "caches near point' href='https://www.geocaching.com/seek/nearest.aspx?lat=" + coords.lat + "&lng=" + coords.lng + (that.parameters.filterFinds ? "&f=1" : "") + "' target='_blank' rel='noopener noreferrer'>List caches</a>";
                        },
                        isValid: function(coords, zoom) { return true; }
                    },
                    {
                        name: "Geograph",
                        action: "getGeograph",
                        getHTML: function(coords, zoom, map) {
                            return "<a href='#' title='Show Geograph images near this point' class='gme-event' data-gme-action='getGeograph' data-gme-coords='" + coords.toUrl() + "'>Geograph</a>";
                        },
                        isValid: function(coords, zoom) {
                            return	bounds_GB.contains(coords) || bounds_DE.contains(coords) || bounds_IE.contains(coords) || bounds_CI.contains(coords);
                        }
                    },
                    {
                        name: "Directions",
                        getHTML: function(coords, zoom, map) {
                            return "<a title='Launch Google Directions from home to this point' target='_blank' rel='noopener noreferrer' href='https://www.google.com/maps/dir/?api=1&origin=" + gmeConfig.env.home.toUrl() + "&destination=" + coords.toUrl() + "'>Directions</a>";
                        },
                        isValid: function(coords, zoom) {
                            return !!gmeConfig.env.home;
                        }
                    },
                    {
                        name: "Wikimapia",
                        getHTML: function(coords, zoom, map) {
                            var centre = map.getCenter();
                            return "<a title='Go to wikimapia' target='_blank' rel='noopener noreferrer' href='http://wikimapia.org/#lat=" + centre.lat + "&lon=" + centre.lng + "&z=" + zoom + "'>Wikimapia</a>";
                        },
                        isValid: function(coords, zoom) {
                            return true;
                        }
                    },
                    {
                        name: "Marker",
                        getHTML: function(coords, zoom, map) {
                            return "<a title='Drop route marker onto map' href='#' class='gme-event' data-gme-action='dropMarker' data-gme-coords='" + coords.toUrl() + "'>Marker</a>";
                        },
                        isValid: function(coords, zoom) {
                            return true;
                        }
                    },
                    {
                        name: "MAGIC",
                        getHTML: function(coords, zoom, map) {
                            var b = map.getBounds();
                            return "<a title='Show MAGIC map of environmentally sensitive areas' target='_blank' rel='noopener noreferrer' href='http://magic.defra.gov.uk/MagicMap.aspx?srs=WGS84&startscale=" + (Math.cos(map.getCenter().lat * L.LatLng.DEG_TO_RAD) * 684090188 * Math.abs(b.getSouthWest().lng - b.getSouthEast().lng)) / map.getSize().x +	"&layers=LandBasedSchemes,12,24:HabitatsAndSpecies,38:Designations,6,10,13,16,34,37,40,72,94&box=" + b.toBBoxString().replace(/,/g,":") + "'>MAGIC</a>";
                        },
                        isValid: function(coords, zoom) {
                            return that.isInUK(coords);
                        }
                    },
                    {
                        name: "Postcode",
                        getHTML: function(coords, zoom, map) {
                            return "<a title='Fetch location data from postcodes.io' href='#' class='gme-event' data-gme-action='getPostcode' data-gme-coords='" + coords.toUrl() + "'>Postcode</a>";
                        },
                        isValid: function(coords, zoom) {
                            return that.isInUK(coords);
                        }
                    },
                    {
                        name: "Height",
                        getHTML: function(coords, zoom, map) {
                            return "<a title='Height of point above sea level' href='#' class='gme-event' data-gme-action='getHeight' data-gme-coords='" + coords.toUrl() + "'>Height</a>";
                        },
                        isValid: function(coords, zoom) {
                            return (coords.lat > -65 && coords.lat < 83);
                        }
                    },
                    {
                        name: "StreetView",
                        getHTML: function(coords, zoom, map) {
                            return "<a title='Launch Google Streetview' target='_blank' rel='noopener noreferrer' href='https://www.google.com/maps/@?api=1&map_action=pano&viewpoint=" + coords.toUrl() + "'>Streetview</a>";
                        },
                        isValid: function(coords, zoom) {
                            return true;
                        }
                    },
                    {
                        name: "MapApp",
                        getHTML: function(coords, zoom, map) {
                            // Open Bing Maps app if available, otherwise use a cross-platform Google Maps URI 
                            return "<a title='Launch Bing Maps' href='bingmaps:?cp=" + coords.lat + "~" + coords.lng + "' target='_blank' rel='noopener noreferrer'><a title='Launch Google Maps' href='https://www.google.com/maps/@?api=1&map_action=map&center=" + coords.toUrl() + "&zoom=" + zoom + "' target='_blank' rel='noopener noreferrer'>Maps</a></a>";
                        },
                        isValid: function(coords, zoom) {
                            return true;
                        }
                    }
                ],
				showRoute:function(e) {
					L.DomEvent.stopPropagation(e);
					this.dropDist(e.latlng);
				},
				toggleCaches:function() {
					if (window.MapSettings && MapSettings.MapLayers && MapSettings.MapLayers.AddGeocacheLayer && MapSettings.MapLayers.RemoveGeocacheLayer) {
						if (MapSettings.MapLayers.Geocache) {
							MapSettings.MapLayers.RemoveGeocacheLayer();
							$(".GME_hide").addClass("gme-button-active").attr("title","Show caches");
						} else {
							MapSettings.MapLayers.AddGeocacheLayer();
							$(".GME_hide").removeClass("gme-button-active").attr("title","Hide caches");
						}
					}
				},
				toggleWpts:function() {
					if (window.MapSettings) {
						if (MapSettings.Map.hasLayer(osmwptlayer)) {
							MapSettings.Map.removeLayer(osmwptlayer);
							$(".GME_wpthide").addClass("gme-button-active").attr("title","Show wpts");
						} else {
							MapSettings.Map.addLayer(osmwptlayer);
							$(".GME_wpthide").removeClass("gme-button-active").attr("title","Hide wpts");
						}
					}
				},
				toggleTool:function(mode) {
					var that = this, widgets = {
						info: {
							on: function() {
								that._map.on("click contextmenu",that.showInfo,that);
								$("#map_canvas").addClass("gme-xhair");
								$(".GME_info").addClass("gme-button-active").attr("title","Disable location info tool");
							},
							off: function() {
								that._map.off("click contextmenu",that.showInfo,that);
								$("#map_canvas").removeClass("gme-xhair");
								$(".GME_info").removeClass("gme-button-active").attr("title","Enable location info tool");
							}
						},
						none: {on: function() {}, off: function() {}},
						route: {
							on: function() {
								that._map.on("click contextmenu",that.showRoute,that);
								$("#map_canvas").addClass("gme-xhair");
								$(".GME_route").addClass("gme-button-active").attr("title","Disable route tool");
							},
							off: function() {
								that._map.off("click contextmenu",that.showRoute,that);
								$("#map_canvas").removeClass("gme-xhair");
								$(".GME_route").removeClass("gme-button-active").attr("title","Enable route tool");
							}
						}
					};
					if (!widgets[mode]) {
						return;
					}
					widgets[this._clickMode].off();
					if (mode == this._clickMode) {
						this._clickMode = "none";
					} else {
						this._clickMode = mode;
						widgets[mode].on();
					}
				},
				search:function (searchVal) {
					var gr, m, call, callbackPrefix = "GME_search_callback", coords=false, marker, that=this;
					function searchGS(searchVal) {
						$(".GME_search_results").addClass("hidden");
						$.getJSON("/api/geocode",{q:searchVal},function(a){
							if (a.status==="success") {
								that._map.panTo(new L.LatLng(a.data.lat,a.data.lng));
							} else {
								alert("Sorry, no results found for "+searchVal);
							}
						});
					}
					function makeCallback2(callname) { callbackCount++; return function(json) {
						var i, j;
						if (json.geonames && json.geonames.length > 0) {
							$(".GME_search_list").empty();
							for (i=0,j=json.geonames.length;i<j;i++) {
								$(".GME_search_list").append("<li><a class='gme-event' data-gme-action='panTo' data-gme-coords='" + json.geonames[i].lat + "," + json.geonames[i].lng + "'>" + json.geonames[i].name + ", " + json.geonames[i].adminName1 + ", " + json.geonames[i].countryCode + "</a></li>");
							}
							$(".GME_search_results").removeClass("hidden");
							$(".GME_search_results.ui-collapsible-collapsed a.ui-collapsible-heading-toggle").click();
							$(".GME_link_GSSearch").off("click");
							$(".GME_link_GSSearch").click(function () { searchGS(searchVal); });
							that._map.panTo(new L.LatLng(json.geonames[0].lat,json.geonames[0].lng));
						} else {
							searchGS(searchVal);
						}
						$("#"+callname).remove();
						if (window[callname] !== undefined) { delete window[callname]; }
					};}
					function makeCallback1(callname) { callbackCount++; return function(json) {
						var newCall=callbackPrefix+callbackCount;
						if (json.countryCode) {
							window[newCall] = makeCallback2(newCall);
							JSONP("http://api.geonames.org/searchJSON?q=" + encodeURIComponent(searchVal) + "&countryBias=" + json.countryCode + "&maxRows=10&username=gme&callback=" + newCall, newCall);
						} else {
							searchGS(searchVal);
						}
						$("#"+callname).remove();
						if (window[callname] !== undefined) { delete window[callname]; }
					};}
					if (searchVal.length > 0) {
						m = searchVal.match(/^\s*(?:z|zoom)\s*(\d\d?)\s*$/i);
						if (m && m.length === 2) {
							this._map.setZoom(m[1]);
							return false;
						}
						m = searchVal.match(/^\s*(?:p|plot)(?:\s+r\s?(\d*\.?\d*))?\s+(.*)/);
						if (m && m.length === 3) {
							coords = parseCoords(m[2]);
							if (coords) {
								if (!isNaN(m[1])) {
									this.dropMarker(L.latLng(coords.lat, coords.lng), m[1]);
								} else {
									L.marker(coords, {icon: L.divIcon()}).addTo(this._map).bindPopup(DMM(coords));
								}
								this._map.panTo(coords);
								return false;
							}
						}
						m = searchVal.match(/^\s*(GC[0123456789ABCDEFGHJKMNOPQRSTVWXYZ]{1,7})\s*$/i);
						if (m && m.length === 2) {
							if (gmeConfig.env.loggedin) {
								this.panToGC(m[1]);
								$(".GME_search_results").addClass("hidden");
								return false;
							}
							alert("You must be logged in to allow GME to get cache coordinates");
							return false;
						}
						gr = parseGR(searchVal);
						if (gr) {
							this._map.panTo(new L.LatLng(gr.lat,gr.lng));
						} else {
							call = callbackPrefix + callbackCount;
							window[call] = makeCallback1(call);
							JSONP("http://api.geonames.org/countryCodeJSON?lat=" + this._map.getCenter().lat + "&lng=" + this._map.getCenter().lng + "&username=gme&radius=100&callback=" + call, call);
						}
					}
					return false;
				},
				panToGC:function(gc) {
          var req = new XMLHttpRequest(),
              map = this._map || e;
          req.addEventListener("load", function (e) {
            var r = req.responseText,
                k = r.indexOf("mapLatLng = {"),
                c;
            if (req.status < 400) {
              try {
                c = JSON.parse(r.substring(k + 12, r.indexOf("}", k) + 1));
                map.panTo(new L.LatLng(c.lat, c.lng));
              } catch (e) {
                console.warn("GME: Couldn't extract cache coordinates:" + e + "\nReceived " + r.length + " bytes, coords at " + k);
              }
            } else {
              if (req.status === 404) {
                alert("Sorry, cache " + gc + " doesn't seem to exist.");
              }
              console.warn("GME: error retrieving cache page to find coords for " + gc + ": " + req.statusText);
            }
          });
          req.open("GET", "https://www.geocaching.com/geocache/" + gc);
          req.send();
				},
				updateScale:function (e, timer) {
					var map = this._map || e;

					if (!map.getBounds) {
						console.warn("updateScale didn't have working map");
						return;
					}
					
					function updateMap() {
						var bound = map.getBounds();
						var width = formatDistance(Math.cos(map.getCenter().lat * L.LatLng.DEG_TO_RAD) * 111319.49079327358 * Math.abs(bound.getSouthWest().lng - bound.getSouthEast().lng));
						$(this._container).find(".gme-scale").html(width);
					}

					if (timer !== undefined) {
						window.clearTimeout(timer.timer);
						timer.timer = window.setTimeout(function() { map.whenReady(updateMap); return false; }, 200);
					} else {
						map.whenReady(updateMap);
					}
				},
				_clickMode: "none"
			},
			zoomWarningObj = {
				options:{position:"topleft"},
				onAdd:function(map){
					var c = L.DomUtil.create("div","leaflet-control-zoomwarning gme-left");
					function checkZoom() {
						if (map.getZoom() > map.layersMaxZoom) {
							map.setZoom(map.layersMaxZoom);
						}
						if (map.getZoom() < map.layersMinZoom) {
							map.setZoom(map.layersMinZoom);
						}
						if (this.getZoom() > 18) {
							c.style.display = "block";
							if (typeof amplify === "object" && typeof amplify.store==="function" && amplify.store("ShowPanel") === false) {
								$(".leaflet-control-zoomwarning").css("left","30px");
							}
						} else {
							c.style.display = "none";
						}
					}
					c.innerHTML = "<a class='gme-button gme-button-l gme-button-r' title='Caches not visible at this zoom level'></a>";
					c.style.display = (map.getZoom() > 18)?"block":"none";
					map.on("zoomend", checkZoom);
					return c;
				}
			};
			
			function GME_load_widget(map) {
				var control = new L.GME_Widget().addTo(map);
				$(control._container).addClass("gme-left").css("top", "20px");
				$(".groundspeak-control-findmylocation").remove();
				if (L.GME_FollowMyLocationControl) {
					map.addControl(new L.GME_FollowMyLocationControl());
				}
				$(".leaflet-control-scale").addClass("gme-control-scale");
				$("a.ToggleSidebar").unbind();
				$("a.ToggleSidebar").click(function(a) {
					a.preventDefault();
					if (window.pnlOpen) {
						window.pnlOpen=false;
						$(".Sidebar").animate({left:"-355px"},500);
						$(".leaflet-control-zoom,.leaflet-control-toolbar,.leaflet-control-scale,.gme-left").animate({left:"30px"},500);
						$(this).removeClass("Open");
					} else {
						window.pnlOpen=true;
						$(".Sidebar").animate({left:"0"},500);
						$(".leaflet-control-zoom,.leaflet-control-toolbar,.leaflet-control-scale,.gme-left").animate({left:"385px"},500);
						$(this).addClass("Open");
					}
					if (typeof amplify === "object" && typeof amplify.store==="function") {
						amplify.store("ShowPanel", window.pnlOpen);
					}
					return false;
				});
				// Trigger reset to update scale and width controls.
				map.fireEvent("viewreset");
				return control;
			}
		},
		xhr: function (e) {
			var node = document.getElementById("gme_jsonp_node"),
				callback = node.getAttribute("data-gme-callback"),
				url = node.text,
				details = {
                    "method": "GET",
                    "url": url,
                    "onload": function(response) {
                        var x = response.responseText,
                            call = x.match(/([a-zA-Z_$][0-9a-zA-Z_$]*)\s*\(/),
                            s;
                        if (call && call.length === 2 && call[1] === callback) {
                            s = document.getElementById("gme_jsonp_node");
                            s.setAttribute("data-gme-callback", callback);
                            s.text = x.substring(x.indexOf("(")+1, x.lastIndexOf(")"));
                            document.dispatchEvent(new Event("GME_XHR_callback"));
                        } else {
                            console.warn("Received: " + x);
                        }
                    }
                };
			if (gmeResources.env.xhr === 'GM4') {
                // GreaseMonkey 4+
                GM.xmlHttpRequest(details);
			} else {
                // Other userscript engines
                setTimeout(function() {
                    GM_xmlhttpRequest(details);
                }, 0);
            }
		}
	}
},
pageTests = [
	["listing", /\/geocache\/GC|\/seek\/cache_details\.aspx|\/seek\/cache_details2\.aspx/],
	["maps", /\/map\//],
	["hide", /\/hide\/planning\.aspx/],
	["type", /\/hide\/typelocation\.aspx/],
	["hide", /\/hide\/waypoints\.aspx/],
	["seek", /\/seek\/$|\/seek\/default\.aspx/],
	["track", /\/track\/map_gm\.aspx/]
],
i, target, target2, targets;

function buildScript() {
	var j, script = "";
	for (j = 1; j < arguments.length; j++) {
		if (typeof arguments[j] === "string" && gmeResources.script.hasOwnProperty(arguments[j])) {
			script += unwrapFunction(gmeResources.script[arguments[j]]);
			gmeResources.env.init.push(arguments[j]);
		}
	}
	insertScript(
		'var GME;\
		(function () {\
			"use strict";\
			function GeocachingMapEnhancements() {\
				var gmeConfig = ' + JSON.stringify({env: gmeResources.env, parameters: gmeResources.parameters}) +	";" +
				script +
			'}\
			GME = new GeocachingMapEnhancements();\
			console.info("Geocaching Map Enhancements v' + gmeResources.parameters.version + ' loaded.");\
		}());',
		arguments[0]
	);
}

function insertCSS(css) {
	if (typeof css !== "string") { console.warn("GME: insertCSS not called with string: " + typeof css); return;	}
	var style = document.createElement('style');
	style.type = 'text/css';
	if (style.styleSheet){
		style.styleSheet.cssText = css;
	} else {
		style.appendChild(document.createTextNode(css));
	}
	document.documentElement.firstChild.appendChild(style);
	var element = document.createElement("div"); element.id = "cesta";document.documentElement.firstChild.appendChild(element);
	
	insertScript(
		'var osmwptlayer = L.layerGroup();MapSettings.Map.addLayer(osmwptlayer);\
		var waypoint = L.icon({iconUrl: "http://www.geocaching.com/images/wpttypes/sm/waypoint.jpg",\
		iconSize: [16, 16],shadowUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAdCAQAAAD8mq+EAAABOklEQVQ4y+3V7U7CMBgF4NNKgyAYFUSjEYPeEsZrNHpLatBgFPkw+IFkY/O0XQRtwWT965q3LUkfTsO2IrB4Cfx9pe5ikfViJUvnXHwzAWmgXEETgxND03nWGlvB9HIpnLHFpk8ttVChiHWW4tzdtk6bIcIUn6xIY0t1XgkVbLJKxNJDE4IJ3jBmTXS2/f4C06qose2QF51cmzklG2LA9sp5LMwinbmNPRxgH1so87NLY3zgBY94wBNGOtdShQ0mHuKYuMZNKw+NuNEBYQddju+I7O1QXF7HEVqsuqHyF00M7eMet6w+5wt0l5ktNDlWcO65NRdc/ow70g7HH7RBdsJqcH7moZdc3iO9YfVceprRtodeZfT6n+b8hQPua66nKeAZDnhzcr+vAadE0NkUcCIGncMBp3+u/5wv7sf1TWI1cMgAAAAASUVORK5CYII=",shadowSize: [16, 16],});\
		var pkg = L.icon({iconUrl: "http://www.geocaching.com/images/wpttypes/sm/pkg.jpg",\
		iconSize: [16, 16],shadowUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAdCAQAAAD8mq+EAAABOklEQVQ4y+3V7U7CMBgF4NNKgyAYFUSjEYPeEsZrNHpLatBgFPkw+IFkY/O0XQRtwWT965q3LUkfTsO2IrB4Cfx9pe5ikfViJUvnXHwzAWmgXEETgxND03nWGlvB9HIpnLHFpk8ttVChiHWW4tzdtk6bIcIUn6xIY0t1XgkVbLJKxNJDE4IJ3jBmTXS2/f4C06qose2QF51cmzklG2LA9sp5LMwinbmNPRxgH1so87NLY3zgBY94wBNGOtdShQ0mHuKYuMZNKw+NuNEBYQddju+I7O1QXF7HEVqsuqHyF00M7eMet6w+5wt0l5ktNDlWcO65NRdc/ow70g7HH7RBdsJqcH7moZdc3iO9YfVceprRtodeZfT6n+b8hQPua66nKeAZDnhzcr+vAadE0NkUcCIGncMBp3+u/5wv7sf1TWI1cMgAAAAASUVORK5CYII=",shadowSize: [16, 16],});\
		var lab = L.icon({iconUrl: "data:image/png;base64, ",\
		iconSize: [20, 34],iconAnchor: [10,34],shadowUrl: "data:image/png;base64, ",shadowSize: [20, 34],});\
		var lab1 = L.icon({iconUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAiCAYAAABfqvm9AAAAB3RJTUUH5AsbDiwd4WA4xgAAAAlwSFlzAAALEwAACxMBAJqcGAAAAARnQU1BAACxjwv8YQUAAAUTSURBVHjarVZrbBRVFP5mdjrdLsv2RWlpygK1taXWQouiPFRAMNEYJIgEsSFqDAE1aCQRQ4IYfhglKgkkkCDyCKQoFhRoiKK2UQxQKbXQIq+2QK3rtjvd7mN22d3OzvXc2W159UGEs/n23nvuOV/OnHvumREwsIwhzCZMINjiOpVwlvALoaU/J6EfnYWwirA8MUnOyLVnIit1OAQGdPgCaLnqROh62E37WwkfE/yDEY4jVKam28pWTHkUSxOzWeaw4YBJiNlFGfs34MeXkQ5hc20tlE7vOdIuIFzojzCPUDOlND+nquAJliwnCtDZnfGLAEtIwOTvvsafbheGWa1aQFVLaaeJb5viZkmEH6aVPVhQXTwHFlEUoqsnoCe7Dj0jGxAadgp6kRP64wkwvTAdG7f8iF0tF7Gvuhqtly+Lnu7u1yPh8CbiCItxwvczMpJLqwqeZBLTcUX1YzBZWXfcIDt68CDeW7sWqtdrJvWa3kceRajdOO/Z0W9ax0DYsgrBqsWA5oZkHwExzQZphBWaokJ3+6C1KRAlK8zPV2B/nQMLZ86EPTUF7R6vS2fsMR7hDNmcMLo8cRSEDa9B3TYdok2DZVYJ5LxsSGlWQIcx8jXXwyaS3Sy8WJaFzx+ZivrF5RiXmZ5BXE9L9Dcp154Fn6Yh4cASyEU5kAtzUN/gNh6vrDil71FP1rthNouYWGxHiNbBQ0vwTuEkRIM68smnxakU8wjTz+xdhlGrCwCraEQBTcerK/7A9opWY46QZowLl53Exm3NxtxMBIAP0ZUPQIgyjM/M4AWQzCNE5K/vjQhkyplBQNLcFsTPewr71kFVg6MzhI/evqGT7SMRaapEkl6KEtEKSTQJPMJuvbMdHKKV8hXRoUUiyLNb8O66s8aaw0KW2SPM+GB9U5+O23M/Jgo40+UCA/PxCOt0IuitWp0b0m/7uomGhq97pWL9RFjNUkwXLzhdi6BpfBLbe6RR6NH1Rk74qyjJsd0gEctS7DDyrDGddoNwalHKrbqIRiUkoebYBaFD8Xbxm8a9/xHTsmN2HhVSihVj5/8OhxIasLDHZplxad90w15My8FndbVcvZOn3ghcLpxrQHMqxAqUP5MVSzrhOcLS+Nh7rRbNzjLsNIdCZbYAjvau1njnuUUK/Jvy2fXdE5j38Ew2KX84e0UQWJTA4uNLhGkPp7LA4adYYNdDzP9VKe8eLkLJTb2jTy5aFuxBxNkJSenEb1+UoXBJLspyqRxoczLldPIbeaj+hA5LUaB1emCZV8H95iPWdO9oX4ZEu86zYOUieh7KZ1oKJIsFEZEKXtcRUYPQPR7KhQ2W+RUwpY9/i1w23+zfX8fmsjt84tPySNM+InAYpcErQUzJhlyyCDOWb8OJ+os1ZDfrdseBCMcSGtbMnZP8YUYhhHBPTCvL+Nbbjpf3H+CraYTjtzuKAxBeJWzdWncaoVCIQYyZMRbFhtZGPq3qj2wwQi6bOhxu9ZuwItAlBTOZ0Kh6cepMs7E3kNNghH8TDu26Fn//EOmOwDUwnfETPfp/CLlUNlxqQ3cgTJdWx08tV7ju0GAOQxEe83sD3hPRbijBIJpbnVx35F4I6S6isTZMudNVaD0aZzx7L4RcTtfYVOwo0vicH3FgMGPpLgjPuVpdCPnDGCq6uyW85m7vhs9lvKvP3w9CxeP0Iv5103Y/CP3RHo23KU7pG8r4bg7FSwjG5133I0JO6EDsg8o1lPF/XHcQefRcnU8AAAAASUVORK5CYII=",\
		iconSize: [20, 34],iconAnchor: [10,34],shadowUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAiCAYAAABfqvm9AAAAB3RJTUUH5AsbDiwd4WA4xgAAAAlwSFlzAAALEwAACxMBAJqcGAAAAARnQU1BAACxjwv8YQUAAAUTSURBVHjarVZrbBRVFP5mdjrdLsv2RWlpygK1taXWQouiPFRAMNEYJIgEsSFqDAE1aCQRQ4IYfhglKgkkkCDyCKQoFhRoiKK2UQxQKbXQIq+2QK3rtjvd7mN22d3OzvXc2W159UGEs/n23nvuOV/OnHvumREwsIwhzCZMINjiOpVwlvALoaU/J6EfnYWwirA8MUnOyLVnIit1OAQGdPgCaLnqROh62E37WwkfE/yDEY4jVKam28pWTHkUSxOzWeaw4YBJiNlFGfs34MeXkQ5hc20tlE7vOdIuIFzojzCPUDOlND+nquAJliwnCtDZnfGLAEtIwOTvvsafbheGWa1aQFVLaaeJb5viZkmEH6aVPVhQXTwHFlEUoqsnoCe7Dj0jGxAadgp6kRP64wkwvTAdG7f8iF0tF7Gvuhqtly+Lnu7u1yPh8CbiCItxwvczMpJLqwqeZBLTcUX1YzBZWXfcIDt68CDeW7sWqtdrJvWa3kceRajdOO/Z0W9ax0DYsgrBqsWA5oZkHwExzQZphBWaokJ3+6C1KRAlK8zPV2B/nQMLZ86EPTUF7R6vS2fsMR7hDNmcMLo8cRSEDa9B3TYdok2DZVYJ5LxsSGlWQIcx8jXXwyaS3Sy8WJaFzx+ZivrF5RiXmZ5BXE9L9Dcp154Fn6Yh4cASyEU5kAtzUN/gNh6vrDil71FP1rthNouYWGxHiNbBQ0vwTuEkRIM68smnxakU8wjTz+xdhlGrCwCraEQBTcerK/7A9opWY46QZowLl53Exm3NxtxMBIAP0ZUPQIgyjM/M4AWQzCNE5K/vjQhkyplBQNLcFsTPewr71kFVg6MzhI/evqGT7SMRaapEkl6KEtEKSTQJPMJuvbMdHKKV8hXRoUUiyLNb8O66s8aaw0KW2SPM+GB9U5+O23M/Jgo40+UCA/PxCOt0IuitWp0b0m/7uomGhq97pWL9RFjNUkwXLzhdi6BpfBLbe6RR6NH1Rk74qyjJsd0gEctS7DDyrDGddoNwalHKrbqIRiUkoebYBaFD8Xbxm8a9/xHTsmN2HhVSihVj5/8OhxIasLDHZplxad90w15My8FndbVcvZOn3ghcLpxrQHMqxAqUP5MVSzrhOcLS+Nh7rRbNzjLsNIdCZbYAjvau1njnuUUK/Jvy2fXdE5j38Ew2KX84e0UQWJTA4uNLhGkPp7LA4adYYNdDzP9VKe8eLkLJTb2jTy5aFuxBxNkJSenEb1+UoXBJLspyqRxoczLldPIbeaj+hA5LUaB1emCZV8H95iPWdO9oX4ZEu86zYOUieh7KZ1oKJIsFEZEKXtcRUYPQPR7KhQ2W+RUwpY9/i1w23+zfX8fmsjt84tPySNM+InAYpcErQUzJhlyyCDOWb8OJ+os1ZDfrdseBCMcSGtbMnZP8YUYhhHBPTCvL+Nbbjpf3H+CraYTjtzuKAxBeJWzdWncaoVCIQYyZMRbFhtZGPq3qj2wwQi6bOhxu9ZuwItAlBTOZ0Kh6cepMs7E3kNNghH8TDu26Fn//EOmOwDUwnfETPfp/CLlUNlxqQ3cgTJdWx08tV7ju0GAOQxEe83sD3hPRbijBIJpbnVx35F4I6S6isTZMudNVaD0aZzx7L4RcTtfYVOwo0vicH3FgMGPpLgjPuVpdCPnDGCq6uyW85m7vhs9lvKvP3w9CxeP0Iv5103Y/CP3RHo23KU7pG8r4bg7FSwjG5133I0JO6EDsg8o1lPF/XHcQefRcnU8AAAAASUVORK5CYII=",shadowSize: [20, 34],});\
		var lab2 = L.icon({iconUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAiCAYAAABfqvm9AAAAB3RJTUUH5AsbES4Zw0F6EAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAARnQU1BAACxjwv8YQUAAATbSURBVHjarZZ/TFNXFMe/77W0dPwoCA1MCVodP0TcpgIBYZvZDzOTJZqIMTKybAuy6RbdH1v2x7YsW5YlxiVubpkOt7llS3QEN4NmiZLREQ2IoIhQQYFiC6tAS+GVFgq0vTv3tbCV35ue9Nvcd+89n573zj2nT8D8tpL0LOkxUnRwzkW6SfqD1DWXkzDH3EOkd0n71BqVbnVyAhJjoyAwoN/pRtfdPnjGxh20Xkb6lDSyEFBPqoiNi954IC8bperlLCEiClAIgX0+xu65R3Biol/4ur4e9gHJSLOFpPa5gI+QDHkbUpLOpz3BtCq1AD+bHb8IsLAw5Px2Gk0OGyIiI71ul2sDrbQGl2XTkMrzN6YmGTKfg1apmhvGzQ8cbb4mw8qrq7E+K0sZqdU2/Os5y/ahTqdlQ3tK/N7i11nHjhfZ3pQMpl8Wx8JEhSw+3peWyTppjfYzgrGSgwdZucEgX5MOT8EeJlmO7tjGOOx47lMsQq1mO4uKWEVNDTNKkiw+5nMKUWQXm5pYD2PMZ94pKzk2homCMBDMAfaowsOYY/er7BuCxcXEsLO1tWyAHDwkf1B8fJaiuWI2sx9uF0zDuOxvvMnWJMbzKEuU9LVpdXIinF4v3r5xFT8bqrElN1d+IB6SnTQZvJXHN+uhUSUj25IQ8lijRv1ISU9CV589kyclLl4bgUO3mrB1+3bkBWF+SyFUpPFAHjDkMeJM6yrEWwpDYOw9HQQfw9oEHc+wVgycHQEXBu5hV+neadhM04avw1vxO0Pm0rMuBU4SnYhHxUgoRYXAb3moX3LC7BhEdkEBVMGUTZnJfgKuCROe93aEwD631qJXGg5EKQpoHrCRH3PyCBvNPTZ5ocP6Lbx+T4hjo6V0Fqwhuhge76B8ZxBFtK7VsFPXWzDp97dwYM342IR1WYwWVTVfoM9dF+I88zaval9C+8BhSF16rIyNpapRwFDfLvTbpUFeaQoEijsaCmzRsBVYkWdEmkIxZ5F85zKiy/YVxiZ6UPv9KuSMRmCzLokV114QRpxjx2jL6anS+2zU7bnz57lWNDS0zQNrw7aMNkRTcoZN6ag7fwvvrNvAirovC9beQRMCnSekOaSRrkRpI2MOHFuOj/PX/5MA+5nAeQvPgLnZh+P7+/DJuk2oUg7j15rr/Kg+g0CfnNW+NpIuq9Vqjf6UFgJvgvR5OdENR4ceN85pKDIjjuTkwxIj4KPKKp7BraRLWMB208+wF1JT2Zp4HVMpFLxO5ebwGjUHy+5XWOOuYj8vV9q7f6azMA/0p5X6hGJj/nYWLiqplfmnF3gvfLL5Iuqu3zbQ5dMzHcV5gB+Yu/ulQ85ugR+LaVOpUOH8i8P41ftzOc4HvEsqK2u8Bo/Hw/jhlaNjPhwxtfDheVLtfwFy+7Lf6nD9Mm4XqEjB6Gy2uCQ0NHfKa/M5LQTsIVX+aA7+/xD0pNsMao78eFz8P0BuFTfuWDDkpiZGianq6uZzlQs5LAa8NCK5pTrfEOyjo+g09fG53+8HyKugpX6cnp3fBe+klxNv3g+Q2zVDtAsnM7x8zFPsXmizcglAo81kg2eE/xksHN1SgWZH7xCcNvkVpm2xzUsB2of7JATfbiwPAjjim/TyRsCRzsU2LyUpEmk0OB58EBFyoBWBFyrbYpv/BpG0KeSXH92QAAAAAElFTkSuQmCC",\
		iconSize: [20, 34],iconAnchor: [10,34],shadowUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAiCAYAAABfqvm9AAAAB3RJTUUH5AsbES4Zw0F6EAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAARnQU1BAACxjwv8YQUAAATbSURBVHjarZZ/TFNXFMe/77W0dPwoCA1MCVodP0TcpgIBYZvZDzOTJZqIMTKybAuy6RbdH1v2x7YsW5YlxiVubpkOt7llS3QEN4NmiZLREQ2IoIhQQYFiC6tAS+GVFgq0vTv3tbCV35ue9Nvcd+89n573zj2nT8D8tpL0LOkxUnRwzkW6SfqD1DWXkzDH3EOkd0n71BqVbnVyAhJjoyAwoN/pRtfdPnjGxh20Xkb6lDSyEFBPqoiNi954IC8bperlLCEiClAIgX0+xu65R3Biol/4ur4e9gHJSLOFpPa5gI+QDHkbUpLOpz3BtCq1AD+bHb8IsLAw5Px2Gk0OGyIiI71ul2sDrbQGl2XTkMrzN6YmGTKfg1apmhvGzQ8cbb4mw8qrq7E+K0sZqdU2/Os5y/ahTqdlQ3tK/N7i11nHjhfZ3pQMpl8Wx8JEhSw+3peWyTppjfYzgrGSgwdZucEgX5MOT8EeJlmO7tjGOOx47lMsQq1mO4uKWEVNDTNKkiw+5nMKUWQXm5pYD2PMZ94pKzk2homCMBDMAfaowsOYY/er7BuCxcXEsLO1tWyAHDwkf1B8fJaiuWI2sx9uF0zDuOxvvMnWJMbzKEuU9LVpdXIinF4v3r5xFT8bqrElN1d+IB6SnTQZvJXHN+uhUSUj25IQ8lijRv1ISU9CV589kyclLl4bgUO3mrB1+3bkBWF+SyFUpPFAHjDkMeJM6yrEWwpDYOw9HQQfw9oEHc+wVgycHQEXBu5hV+neadhM04avw1vxO0Pm0rMuBU4SnYhHxUgoRYXAb3moX3LC7BhEdkEBVMGUTZnJfgKuCROe93aEwD631qJXGg5EKQpoHrCRH3PyCBvNPTZ5ocP6Lbx+T4hjo6V0Fqwhuhge76B8ZxBFtK7VsFPXWzDp97dwYM342IR1WYwWVTVfoM9dF+I88zaval9C+8BhSF16rIyNpapRwFDfLvTbpUFeaQoEijsaCmzRsBVYkWdEmkIxZ5F85zKiy/YVxiZ6UPv9KuSMRmCzLokV114QRpxjx2jL6anS+2zU7bnz57lWNDS0zQNrw7aMNkRTcoZN6ag7fwvvrNvAirovC9beQRMCnSekOaSRrkRpI2MOHFuOj/PX/5MA+5nAeQvPgLnZh+P7+/DJuk2oUg7j15rr/Kg+g0CfnNW+NpIuq9Vqjf6UFgJvgvR5OdENR4ceN85pKDIjjuTkwxIj4KPKKp7BraRLWMB208+wF1JT2Zp4HVMpFLxO5ebwGjUHy+5XWOOuYj8vV9q7f6azMA/0p5X6hGJj/nYWLiqplfmnF3gvfLL5Iuqu3zbQ5dMzHcV5gB+Yu/ulQ85ugR+LaVOpUOH8i8P41ftzOc4HvEsqK2u8Bo/Hw/jhlaNjPhwxtfDheVLtfwFy+7Lf6nD9Mm4XqEjB6Gy2uCQ0NHfKa/M5LQTsIVX+aA7+/xD0pNsMao78eFz8P0BuFTfuWDDkpiZGianq6uZzlQs5LAa8NCK5pTrfEOyjo+g09fG53+8HyKugpX6cnp3fBe+klxNv3g+Q2zVDtAsnM7x8zFPsXmizcglAo81kg2eE/xksHN1SgWZH7xCcNvkVpm2xzUsB2of7JATfbiwPAjjim/TyRsCRzsU2LyUpEmk0OB58EBFyoBWBFyrbYpv/BpG0KeSXH92QAAAAAElFTkSuQmCC",shadowSize: [20, 34],});\
		var labok = L.icon({iconUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAiCAYAAABfqvm9AAAAB3RJTUUH5AsbERItkQb3WgAAAAlwSFlzAAALEwAACxMBAJqcGAAAAARnQU1BAACxjwv8YQUAAAS+SURBVHjarZZ7TNtVFMfPry0tlUJ5VZgi2G08xhAdewRkOrO4RaMJizrJJn84w9CpcX9oYnQuxn+My1yIW+IDTLZFMxQxm0hMhEhDttDhYDyrIBTWsjH65tcHa6Ht8dxfC7GVAjpO8m3u7557P72/e84998dBbMshPUl6mJQU7nOTBki/kfRLTeKW6LuH9C7piEwuVa3PzoDMlETgEMDk9ID+xjR47/js5K8jfUxyLQdUk5pS0pJK3irbDjWy+zAjIRFAzIXGBRBve1xQP2fiPu/qAquZ11HvC6ThpYAbSZqyLblZLfmPoVIq4yCI/16/CADj4mDHxe+g126BBIXC73G7t5BnKOwWTE5qLC/Jy9IU7QGlRLo0jFkQ4HR/jwBrbG+Hh7ZtkyiUymv/2GfBPlSplOg4UB30V72Go/tewsO5hahOTcM4kVgQax/JL8Ix8tF4JBhWHz2KjRqN8Ew6uQBbRzKe3vc0MtiXpbswQSbD5w8exKaODtTxvCDWZn1ikQhbe3txEnEBhNkpySjiOHM4BnBAGh+H9spX8CuCpSUn46XOTjTTBC8pGBZrX6LVXDUY8NzIzkUYk/WNN3FDZjprV0voZ+v67Exw+v3wTt/v8K2mHZ4oLRU2xEuykubDr/LIo2qQS7OhlLsSsa2Js0HILcgC/bS1iAUlLV2ZACf+6IW9FRVQFoZxlClyki8UB3B4dfDj0IOQwUVmGm0TcAGETRkqFmGlKJQ7HPxqvg37aw4vwqJNGb8Z3t4a2ZerujeUSZQRxSIFSERijgEdJt4JBrsNtu/cCdIo0Li1Hgam3oMHov7klHYd3ORnhDZFBPptFtpQdDJgt2HSIjhGp74Gf9AbMbHbWAPP3P9JRN9Vx0Xw+m3Cm4FIBEOb5NhwfRDmg8FBBuzw3ZmbSk1WQlvHZzDt0UZMjn5N7cxPMGw+CbxeDTkpKXRqxKDpGuZMVt7GThoD3iLVe+a8MNSigB5zLcSyOl0BdOorwObuhH4auyc9E1y+AH7a3cXc50hjC2MVpBGZTIrvN2yMyLEF1ekKhWSu123G4z8UYFK8HCdfPBR8qryY+VkpS41eQD4LUKJSgccu5EXATvWExKDHLuRT8ivxi/Ld+NyuEuZnAShegETnRwnpikwmk6sblJQ+KCBfzvSAfVQNfT/LQduig9od5WBM5uCj5jYWwb2ky7CMVdLf4LN5ebghXYVSsZidU6E4vErFwVh5CLv3VwXZcaWxr0dP5mJAv8lRZ1TpyiswXiShUhZcdLBa+Hh/K2ivj2jocXf0RFEM4HHDhIk/4ZzgWFosmlQKTc5bDMaePlhqYizgDZYldd094PV6kSWvsDoMQO34IGu2kDr/C5DZGdOU3f29z8rRIQUUi2HQzcO1fiHVzsSatBxwktR83hC+fwh61mMAKo7sGm39P0BmTX1/GcHhoSJGgWnTT7C+5uUmrAS87OI9vDbgAOvsLIyNT7O+X+4GyAr2YJeP9i7oBv+8nxEH7gbIrEeT5IazhX7WZiH2LDdYsgqgzjJuAa+LXQbLr261QIP9pgOcFuET5s+1AFpnpnkI3wDGtQC6AvN+VggY0rnS4NUEhSfNhtu2tVghA05B6IPKstLgvwECiB5Fj7Q5BQAAAABJRU5ErkJggg==",\
		iconSize: [20, 34],iconAnchor: [10,34],shadowUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAiCAYAAABfqvm9AAAAB3RJTUUH5AsbERItkQb3WgAAAAlwSFlzAAALEwAACxMBAJqcGAAAAARnQU1BAACxjwv8YQUAAAS+SURBVHjarZZ7TNtVFMfPry0tlUJ5VZgi2G08xhAdewRkOrO4RaMJizrJJn84w9CpcX9oYnQuxn+My1yIW+IDTLZFMxQxm0hMhEhDttDhYDyrIBTWsjH65tcHa6Ht8dxfC7GVAjpO8m3u7557P72/e84998dBbMshPUl6mJQU7nOTBki/kfRLTeKW6LuH9C7piEwuVa3PzoDMlETgEMDk9ID+xjR47/js5K8jfUxyLQdUk5pS0pJK3irbDjWy+zAjIRFAzIXGBRBve1xQP2fiPu/qAquZ11HvC6ThpYAbSZqyLblZLfmPoVIq4yCI/16/CADj4mDHxe+g126BBIXC73G7t5BnKOwWTE5qLC/Jy9IU7QGlRLo0jFkQ4HR/jwBrbG+Hh7ZtkyiUymv/2GfBPlSplOg4UB30V72Go/tewsO5hahOTcM4kVgQax/JL8Ix8tF4JBhWHz2KjRqN8Ew6uQBbRzKe3vc0MtiXpbswQSbD5w8exKaODtTxvCDWZn1ikQhbe3txEnEBhNkpySjiOHM4BnBAGh+H9spX8CuCpSUn46XOTjTTBC8pGBZrX6LVXDUY8NzIzkUYk/WNN3FDZjprV0voZ+v67Exw+v3wTt/v8K2mHZ4oLRU2xEuykubDr/LIo2qQS7OhlLsSsa2Js0HILcgC/bS1iAUlLV2ZACf+6IW9FRVQFoZxlClyki8UB3B4dfDj0IOQwUVmGm0TcAGETRkqFmGlKJQ7HPxqvg37aw4vwqJNGb8Z3t4a2ZerujeUSZQRxSIFSERijgEdJt4JBrsNtu/cCdIo0Li1Hgam3oMHov7klHYd3ORnhDZFBPptFtpQdDJgt2HSIjhGp74Gf9AbMbHbWAPP3P9JRN9Vx0Xw+m3Cm4FIBEOb5NhwfRDmg8FBBuzw3ZmbSk1WQlvHZzDt0UZMjn5N7cxPMGw+CbxeDTkpKXRqxKDpGuZMVt7GThoD3iLVe+a8MNSigB5zLcSyOl0BdOorwObuhH4auyc9E1y+AH7a3cXc50hjC2MVpBGZTIrvN2yMyLEF1ekKhWSu123G4z8UYFK8HCdfPBR8qryY+VkpS41eQD4LUKJSgccu5EXATvWExKDHLuRT8ivxi/Ld+NyuEuZnAShegETnRwnpikwmk6sblJQ+KCBfzvSAfVQNfT/LQduig9od5WBM5uCj5jYWwb2ky7CMVdLf4LN5ebghXYVSsZidU6E4vErFwVh5CLv3VwXZcaWxr0dP5mJAv8lRZ1TpyiswXiShUhZcdLBa+Hh/K2ivj2jocXf0RFEM4HHDhIk/4ZzgWFosmlQKTc5bDMaePlhqYizgDZYldd094PV6kSWvsDoMQO34IGu2kDr/C5DZGdOU3f29z8rRIQUUi2HQzcO1fiHVzsSatBxwktR83hC+fwh61mMAKo7sGm39P0BmTX1/GcHhoSJGgWnTT7C+5uUmrAS87OI9vDbgAOvsLIyNT7O+X+4GyAr2YJeP9i7oBv+8nxEH7gbIrEeT5IazhX7WZiH2LDdYsgqgzjJuAa+LXQbLr261QIP9pgOcFuET5s+1AFpnpnkI3wDGtQC6AvN+VggY0rnS4NUEhSfNhtu2tVghA05B6IPKstLgvwECiB5Fj7Q5BQAAAABJRU5ErkJggg==",shadowSize: [20, 34],});\
		var lb1 = L.icon({iconUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAiCAYAAABfqvm9AAAAB3RJTUUH5wkTDh8waTQIogAAAAlwSFlzAAALEwAACxMBAJqcGAAAAARnQU1BAACxjwv8YQUAAARuSURBVHjarZZ/TBtlGMe/dxxHVwt0/HBdgx2SDhgSZDWSzKlxBE1czFyIIcxsxKiZm5rFaOLURGP2x6L7QxNmZoLLFhWrMjYdIf6BG8QfGUMZY7C5QQoDxFrKrVB6rW253vnctUNdj0IcT/Ptve9zz/u55573vfeOweK2jlRDupeUlfCJpAHSWdKI3iBGx2ck7SftzVjF5xfZ1sCyOhOMAkzNBTEy5kH4r4iPzjeRDpICqYB3k1pX52Y59m26H7szrMqaOzKBNCYeF1OUP4MBfBKdYo709EDw+q+Qt3wxoJ3UtWnj+oL2koeUbD6Dgawk588CSno6qr75irnom046zSWOq0gtmx3FBWfvqQGnyEzszQpIrnbI3lFIXi+4vBywlmLw9q1M464voMJaOjtRV1196/U0ez0/P3tje8nDCsFwXQwglb3We06DdZw+rTspa0k9jdsfv+tF0zowH+9HqP1pQPKBs+WBzcmi7EyQBBGyb46RJgSwnAmGJ5w42etG3ZYtScAdvCHd6XlyF7I/egFicy24YisMlYWLrohw/xikYTdMz55BWvaGpBreV2SzYE6SkH6qAXxZAfjSAvT1+7QAR7l5Ifh8nw8GA4vKchvC1A+1NejNGXIvfbkHa98qAUwsFd1KtyvjmX2/4JhzVGsjLGnHuj3n0XjUpbUNdFFgTn+Wo799q3V4qpkGIHNNhHCmuXShHxIluL1hvPvyPz7edif9DyVlOCN7J6GKNZmILkOKRmG3GfHKgQGtr8pIkdY8A944dHnBp8XrZNgrE+AmX1YD6XfsQKXmUfs3zXmoEiYDF/ex0DUV+APL8fFeiMB8fK077ImrSwtA5YEyM/MfX1TSBf7B5ljjcbMiOLMJhbU/wy2E9RJQn0Wm0GLAcMuDWrzeLNMy2aZJ8ghEBXY+ZokXnbSVtDtxTNylUl9j0eIkt5AE/PfmUBI4vP4aZzYias5B9au9KHWJ+CwBUm+ynuSmddlxsALwCYws8ch87mJyhgkbMj7VjKiHNgLBix8/cKC0oQiOIpNWlyqqadXzdnS+R5MlCLRhzCrG7U4lVYaaxW5cVUKtlItE9cwxgzNSxiwteFlGVAxBnp2lWmTBWOtEWu6Gl2jIkZTAhH0e6X5/Z/RyCwHckKUo1JXAmq3gK+rxyN6j6O4b6qK46iUzTFghqf/tbY9mv5NfCiYyH/fyPE74J7Hj5Cm1t5l0TneWdWyM1NTUewHhcFgBGw9TlBg+HB1Um+16sFRA1Q5PuX3i1xGBAcdCSUvDoOjHr5dc2rnFBqUC/k5q+3T8WrxH0OPBcSiyor5GO/4PULXW/uEJzAQjtBBlfD9yXfW1pRqwFPCngD/o747NQAiF4Br1qL7vbgeoPluDPRGqnSxCmpdU4sDtAFW70JUl4niZtrOoUxxMFcwtA3hlenQa4UAES2W3XOC4b3IGc9Pau/rqSgCFWY8fia+biZUABmLzkraxQu81d4stZ1L8pFCifWMlMlSBbsQ/qKaXCv4bhvC8FvqK9J0AAAAASUVORK5CYII=",\
		iconSize: [20, 34],iconAnchor: [10,34],shadowUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAiCAYAAABfqvm9AAAAB3RJTUUH5wkTDh8waTQIogAAAAlwSFlzAAALEwAACxMBAJqcGAAAAARnQU1BAACxjwv8YQUAAARuSURBVHjarZZ/TBtlGMe/dxxHVwt0/HBdgx2SDhgSZDWSzKlxBE1czFyIIcxsxKiZm5rFaOLURGP2x6L7QxNmZoLLFhWrMjYdIf6BG8QfGUMZY7C5QQoDxFrKrVB6rW253vnctUNdj0IcT/Ptve9zz/u55573vfeOweK2jlRDupeUlfCJpAHSWdKI3iBGx2ck7SftzVjF5xfZ1sCyOhOMAkzNBTEy5kH4r4iPzjeRDpICqYB3k1pX52Y59m26H7szrMqaOzKBNCYeF1OUP4MBfBKdYo709EDw+q+Qt3wxoJ3UtWnj+oL2koeUbD6Dgawk588CSno6qr75irnom046zSWOq0gtmx3FBWfvqQGnyEzszQpIrnbI3lFIXi+4vBywlmLw9q1M464voMJaOjtRV1196/U0ez0/P3tje8nDCsFwXQwglb3We06DdZw+rTspa0k9jdsfv+tF0zowH+9HqP1pQPKBs+WBzcmi7EyQBBGyb46RJgSwnAmGJ5w42etG3ZYtScAdvCHd6XlyF7I/egFicy24YisMlYWLrohw/xikYTdMz55BWvaGpBreV2SzYE6SkH6qAXxZAfjSAvT1+7QAR7l5Ifh8nw8GA4vKchvC1A+1NejNGXIvfbkHa98qAUwsFd1KtyvjmX2/4JhzVGsjLGnHuj3n0XjUpbUNdFFgTn+Wo799q3V4qpkGIHNNhHCmuXShHxIluL1hvPvyPz7edif9DyVlOCN7J6GKNZmILkOKRmG3GfHKgQGtr8pIkdY8A944dHnBp8XrZNgrE+AmX1YD6XfsQKXmUfs3zXmoEiYDF/ex0DUV+APL8fFeiMB8fK077ImrSwtA5YEyM/MfX1TSBf7B5ljjcbMiOLMJhbU/wy2E9RJQn0Wm0GLAcMuDWrzeLNMy2aZJ8ghEBXY+ZokXnbSVtDtxTNylUl9j0eIkt5AE/PfmUBI4vP4aZzYias5B9au9KHWJ+CwBUm+ynuSmddlxsALwCYws8ch87mJyhgkbMj7VjKiHNgLBix8/cKC0oQiOIpNWlyqqadXzdnS+R5MlCLRhzCrG7U4lVYaaxW5cVUKtlItE9cwxgzNSxiwteFlGVAxBnp2lWmTBWOtEWu6Gl2jIkZTAhH0e6X5/Z/RyCwHckKUo1JXAmq3gK+rxyN6j6O4b6qK46iUzTFghqf/tbY9mv5NfCiYyH/fyPE74J7Hj5Cm1t5l0TneWdWyM1NTUewHhcFgBGw9TlBg+HB1Um+16sFRA1Q5PuX3i1xGBAcdCSUvDoOjHr5dc2rnFBqUC/k5q+3T8WrxH0OPBcSiyor5GO/4PULXW/uEJzAQjtBBlfD9yXfW1pRqwFPCngD/o747NQAiF4Br1qL7vbgeoPluDPRGqnSxCmpdU4sDtAFW70JUl4niZtrOoUxxMFcwtA3hlenQa4UAES2W3XOC4b3IGc9Pau/rqSgCFWY8fia+biZUABmLzkraxQu81d4stZ1L8pFCifWMlMlSBbsQ/qKaXCv4bhvC8FvqK9J0AAAAASUVORK5CYII=",shadowSize: [20, 34],});\
		var lb = L.icon({iconUrl: "data:image/png;base64, ",\
		iconSize: [14, 24],iconAnchor: [7,24],shadowUrl: "data:image/png;base64, ",shadowSize: [14, 24],});\
		var lb2 = L.icon({iconUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAiCAYAAABfqvm9AAAAB3RJTUUH5AsbES4Zw0F6EAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAARnQU1BAACxjwv8YQUAAATbSURBVHjarZZ/TFNXFMe/77W0dPwoCA1MCVodP0TcpgIBYZvZDzOTJZqIMTKybAuy6RbdH1v2x7YsW5YlxiVubpkOt7llS3QEN4NmiZLREQ2IoIhQQYFiC6tAS+GVFgq0vTv3tbCV35ue9Nvcd+89n573zj2nT8D8tpL0LOkxUnRwzkW6SfqD1DWXkzDH3EOkd0n71BqVbnVyAhJjoyAwoN/pRtfdPnjGxh20Xkb6lDSyEFBPqoiNi954IC8bperlLCEiClAIgX0+xu65R3Biol/4ur4e9gHJSLOFpPa5gI+QDHkbUpLOpz3BtCq1AD+bHb8IsLAw5Px2Gk0OGyIiI71ul2sDrbQGl2XTkMrzN6YmGTKfg1apmhvGzQ8cbb4mw8qrq7E+K0sZqdU2/Os5y/ahTqdlQ3tK/N7i11nHjhfZ3pQMpl8Wx8JEhSw+3peWyTppjfYzgrGSgwdZucEgX5MOT8EeJlmO7tjGOOx47lMsQq1mO4uKWEVNDTNKkiw+5nMKUWQXm5pYD2PMZ94pKzk2homCMBDMAfaowsOYY/er7BuCxcXEsLO1tWyAHDwkf1B8fJaiuWI2sx9uF0zDuOxvvMnWJMbzKEuU9LVpdXIinF4v3r5xFT8bqrElN1d+IB6SnTQZvJXHN+uhUSUj25IQ8lijRv1ISU9CV589kyclLl4bgUO3mrB1+3bkBWF+SyFUpPFAHjDkMeJM6yrEWwpDYOw9HQQfw9oEHc+wVgycHQEXBu5hV+neadhM04avw1vxO0Pm0rMuBU4SnYhHxUgoRYXAb3moX3LC7BhEdkEBVMGUTZnJfgKuCROe93aEwD631qJXGg5EKQpoHrCRH3PyCBvNPTZ5ocP6Lbx+T4hjo6V0Fqwhuhge76B8ZxBFtK7VsFPXWzDp97dwYM342IR1WYwWVTVfoM9dF+I88zaval9C+8BhSF16rIyNpapRwFDfLvTbpUFeaQoEijsaCmzRsBVYkWdEmkIxZ5F85zKiy/YVxiZ6UPv9KuSMRmCzLokV114QRpxjx2jL6anS+2zU7bnz57lWNDS0zQNrw7aMNkRTcoZN6ag7fwvvrNvAirovC9beQRMCnSekOaSRrkRpI2MOHFuOj/PX/5MA+5nAeQvPgLnZh+P7+/DJuk2oUg7j15rr/Kg+g0CfnNW+NpIuq9Vqjf6UFgJvgvR5OdENR4ceN85pKDIjjuTkwxIj4KPKKp7BraRLWMB208+wF1JT2Zp4HVMpFLxO5ebwGjUHy+5XWOOuYj8vV9q7f6azMA/0p5X6hGJj/nYWLiqplfmnF3gvfLL5Iuqu3zbQ5dMzHcV5gB+Yu/ulQ85ugR+LaVOpUOH8i8P41ftzOc4HvEsqK2u8Bo/Hw/jhlaNjPhwxtfDheVLtfwFy+7Lf6nD9Mm4XqEjB6Gy2uCQ0NHfKa/M5LQTsIVX+aA7+/xD0pNsMao78eFz8P0BuFTfuWDDkpiZGianq6uZzlQs5LAa8NCK5pTrfEOyjo+g09fG53+8HyKugpX6cnp3fBe+klxNv3g+Q2zVDtAsnM7x8zFPsXmizcglAo81kg2eE/xksHN1SgWZH7xCcNvkVpm2xzUsB2of7JATfbiwPAjjim/TyRsCRzsU2LyUpEmk0OB58EBFyoBWBFyrbYpv/BpG0KeSXH92QAAAAAElFTkSuQmCC",\
		iconSize: [14, 24],iconAnchor: [7,24],shadowUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAiCAYAAABfqvm9AAAAB3RJTUUH5AsbES4Zw0F6EAAAAAlwSFlzAAALEwAACxMBAJqcGAAAAARnQU1BAACxjwv8YQUAAATbSURBVHjarZZ/TFNXFMe/77W0dPwoCA1MCVodP0TcpgIBYZvZDzOTJZqIMTKybAuy6RbdH1v2x7YsW5YlxiVubpkOt7llS3QEN4NmiZLREQ2IoIhQQYFiC6tAS+GVFgq0vTv3tbCV35ue9Nvcd+89n573zj2nT8D8tpL0LOkxUnRwzkW6SfqD1DWXkzDH3EOkd0n71BqVbnVyAhJjoyAwoN/pRtfdPnjGxh20Xkb6lDSyEFBPqoiNi954IC8bperlLCEiClAIgX0+xu65R3Biol/4ur4e9gHJSLOFpPa5gI+QDHkbUpLOpz3BtCq1AD+bHb8IsLAw5Px2Gk0OGyIiI71ul2sDrbQGl2XTkMrzN6YmGTKfg1apmhvGzQ8cbb4mw8qrq7E+K0sZqdU2/Os5y/ahTqdlQ3tK/N7i11nHjhfZ3pQMpl8Wx8JEhSw+3peWyTppjfYzgrGSgwdZucEgX5MOT8EeJlmO7tjGOOx47lMsQq1mO4uKWEVNDTNKkiw+5nMKUWQXm5pYD2PMZ94pKzk2homCMBDMAfaowsOYY/er7BuCxcXEsLO1tWyAHDwkf1B8fJaiuWI2sx9uF0zDuOxvvMnWJMbzKEuU9LVpdXIinF4v3r5xFT8bqrElN1d+IB6SnTQZvJXHN+uhUSUj25IQ8lijRv1ISU9CV589kyclLl4bgUO3mrB1+3bkBWF+SyFUpPFAHjDkMeJM6yrEWwpDYOw9HQQfw9oEHc+wVgycHQEXBu5hV+neadhM04avw1vxO0Pm0rMuBU4SnYhHxUgoRYXAb3moX3LC7BhEdkEBVMGUTZnJfgKuCROe93aEwD631qJXGg5EKQpoHrCRH3PyCBvNPTZ5ocP6Lbx+T4hjo6V0Fqwhuhge76B8ZxBFtK7VsFPXWzDp97dwYM342IR1WYwWVTVfoM9dF+I88zaval9C+8BhSF16rIyNpapRwFDfLvTbpUFeaQoEijsaCmzRsBVYkWdEmkIxZ5F85zKiy/YVxiZ6UPv9KuSMRmCzLokV114QRpxjx2jL6anS+2zU7bnz57lWNDS0zQNrw7aMNkRTcoZN6ag7fwvvrNvAirovC9beQRMCnSekOaSRrkRpI2MOHFuOj/PX/5MA+5nAeQvPgLnZh+P7+/DJuk2oUg7j15rr/Kg+g0CfnNW+NpIuq9Vqjf6UFgJvgvR5OdENR4ceN85pKDIjjuTkwxIj4KPKKp7BraRLWMB208+wF1JT2Zp4HVMpFLxO5ebwGjUHy+5XWOOuYj8vV9q7f6azMA/0p5X6hGJj/nYWLiqplfmnF3gvfLL5Iuqu3zbQ5dMzHcV5gB+Yu/ulQ85ugR+LaVOpUOH8i8P41ftzOc4HvEsqK2u8Bo/Hw/jhlaNjPhwxtfDheVLtfwFy+7Lf6nD9Mm4XqEjB6Gy2uCQ0NHfKa/M5LQTsIVX+aA7+/xD0pNsMao78eFz8P0BuFTfuWDDkpiZGianq6uZzlQs5LAa8NCK5pTrfEOyjo+g09fG53+8HyKugpX6cnp3fBe+klxNv3g+Q2zVDtAsnM7x8zFPsXmizcglAo81kg2eE/xksHN1SgWZH7xCcNvkVpm2xzUsB2of7JATfbiwPAjjim/TyRsCRzsU2LyUpEmk0OB58EBFyoBWBFyrbYpv/BpG0KeSXH92QAAAAAElFTkSuQmCC",shadowSize: [14, 24],});\
		var lbok = L.icon({iconUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAiCAYAAABfqvm9AAAAB3RJTUUH5AsbERItkQb3WgAAAAlwSFlzAAALEwAACxMBAJqcGAAAAARnQU1BAACxjwv8YQUAAAS+SURBVHjarZZ7TNtVFMfPry0tlUJ5VZgi2G08xhAdewRkOrO4RaMJizrJJn84w9CpcX9oYnQuxn+My1yIW+IDTLZFMxQxm0hMhEhDttDhYDyrIBTWsjH65tcHa6Ht8dxfC7GVAjpO8m3u7557P72/e84998dBbMshPUl6mJQU7nOTBki/kfRLTeKW6LuH9C7piEwuVa3PzoDMlETgEMDk9ID+xjR47/js5K8jfUxyLQdUk5pS0pJK3irbDjWy+zAjIRFAzIXGBRBve1xQP2fiPu/qAquZ11HvC6ThpYAbSZqyLblZLfmPoVIq4yCI/16/CADj4mDHxe+g126BBIXC73G7t5BnKOwWTE5qLC/Jy9IU7QGlRLo0jFkQ4HR/jwBrbG+Hh7ZtkyiUymv/2GfBPlSplOg4UB30V72Go/tewsO5hahOTcM4kVgQax/JL8Ix8tF4JBhWHz2KjRqN8Ew6uQBbRzKe3vc0MtiXpbswQSbD5w8exKaODtTxvCDWZn1ikQhbe3txEnEBhNkpySjiOHM4BnBAGh+H9spX8CuCpSUn46XOTjTTBC8pGBZrX6LVXDUY8NzIzkUYk/WNN3FDZjprV0voZ+v67Exw+v3wTt/v8K2mHZ4oLRU2xEuykubDr/LIo2qQS7OhlLsSsa2Js0HILcgC/bS1iAUlLV2ZACf+6IW9FRVQFoZxlClyki8UB3B4dfDj0IOQwUVmGm0TcAGETRkqFmGlKJQ7HPxqvg37aw4vwqJNGb8Z3t4a2ZerujeUSZQRxSIFSERijgEdJt4JBrsNtu/cCdIo0Li1Hgam3oMHov7klHYd3ORnhDZFBPptFtpQdDJgt2HSIjhGp74Gf9AbMbHbWAPP3P9JRN9Vx0Xw+m3Cm4FIBEOb5NhwfRDmg8FBBuzw3ZmbSk1WQlvHZzDt0UZMjn5N7cxPMGw+CbxeDTkpKXRqxKDpGuZMVt7GThoD3iLVe+a8MNSigB5zLcSyOl0BdOorwObuhH4auyc9E1y+AH7a3cXc50hjC2MVpBGZTIrvN2yMyLEF1ekKhWSu123G4z8UYFK8HCdfPBR8qryY+VkpS41eQD4LUKJSgccu5EXATvWExKDHLuRT8ivxi/Ld+NyuEuZnAShegETnRwnpikwmk6sblJQ+KCBfzvSAfVQNfT/LQduig9od5WBM5uCj5jYWwb2ky7CMVdLf4LN5ebghXYVSsZidU6E4vErFwVh5CLv3VwXZcaWxr0dP5mJAv8lRZ1TpyiswXiShUhZcdLBa+Hh/K2ivj2jocXf0RFEM4HHDhIk/4ZzgWFosmlQKTc5bDMaePlhqYizgDZYldd094PV6kSWvsDoMQO34IGu2kDr/C5DZGdOU3f29z8rRIQUUi2HQzcO1fiHVzsSatBxwktR83hC+fwh61mMAKo7sGm39P0BmTX1/GcHhoSJGgWnTT7C+5uUmrAS87OI9vDbgAOvsLIyNT7O+X+4GyAr2YJeP9i7oBv+8nxEH7gbIrEeT5IazhX7WZiH2LDdYsgqgzjJuAa+LXQbLr261QIP9pgOcFuET5s+1AFpnpnkI3wDGtQC6AvN+VggY0rnS4NUEhSfNhtu2tVghA05B6IPKstLgvwECiB5Fj7Q5BQAAAABJRU5ErkJggg==",\
		iconSize: [14, 24],iconAnchor: [7,24],shadowUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAiCAYAAABfqvm9AAAAB3RJTUUH5AsbERItkQb3WgAAAAlwSFlzAAALEwAACxMBAJqcGAAAAARnQU1BAACxjwv8YQUAAAS+SURBVHjarZZ7TNtVFMfPry0tlUJ5VZgi2G08xhAdewRkOrO4RaMJizrJJn84w9CpcX9oYnQuxn+My1yIW+IDTLZFMxQxm0hMhEhDttDhYDyrIBTWsjH65tcHa6Ht8dxfC7GVAjpO8m3u7557P72/e84998dBbMshPUl6mJQU7nOTBki/kfRLTeKW6LuH9C7piEwuVa3PzoDMlETgEMDk9ID+xjR47/js5K8jfUxyLQdUk5pS0pJK3irbDjWy+zAjIRFAzIXGBRBve1xQP2fiPu/qAquZ11HvC6ThpYAbSZqyLblZLfmPoVIq4yCI/16/CADj4mDHxe+g126BBIXC73G7t5BnKOwWTE5qLC/Jy9IU7QGlRLo0jFkQ4HR/jwBrbG+Hh7ZtkyiUymv/2GfBPlSplOg4UB30V72Go/tewsO5hahOTcM4kVgQax/JL8Ix8tF4JBhWHz2KjRqN8Ew6uQBbRzKe3vc0MtiXpbswQSbD5w8exKaODtTxvCDWZn1ikQhbe3txEnEBhNkpySjiOHM4BnBAGh+H9spX8CuCpSUn46XOTjTTBC8pGBZrX6LVXDUY8NzIzkUYk/WNN3FDZjprV0voZ+v67Exw+v3wTt/v8K2mHZ4oLRU2xEuykubDr/LIo2qQS7OhlLsSsa2Js0HILcgC/bS1iAUlLV2ZACf+6IW9FRVQFoZxlClyki8UB3B4dfDj0IOQwUVmGm0TcAGETRkqFmGlKJQ7HPxqvg37aw4vwqJNGb8Z3t4a2ZerujeUSZQRxSIFSERijgEdJt4JBrsNtu/cCdIo0Li1Hgam3oMHov7klHYd3ORnhDZFBPptFtpQdDJgt2HSIjhGp74Gf9AbMbHbWAPP3P9JRN9Vx0Xw+m3Cm4FIBEOb5NhwfRDmg8FBBuzw3ZmbSk1WQlvHZzDt0UZMjn5N7cxPMGw+CbxeDTkpKXRqxKDpGuZMVt7GThoD3iLVe+a8MNSigB5zLcSyOl0BdOorwObuhH4auyc9E1y+AH7a3cXc50hjC2MVpBGZTIrvN2yMyLEF1ekKhWSu123G4z8UYFK8HCdfPBR8qryY+VkpS41eQD4LUKJSgccu5EXATvWExKDHLuRT8ivxi/Ld+NyuEuZnAShegETnRwnpikwmk6sblJQ+KCBfzvSAfVQNfT/LQduig9od5WBM5uCj5jYWwb2ky7CMVdLf4LN5ebghXYVSsZidU6E4vErFwVh5CLv3VwXZcaWxr0dP5mJAv8lRZ1TpyiswXiShUhZcdLBa+Hh/K2ivj2jocXf0RFEM4HHDhIk/4ZzgWFosmlQKTc5bDMaePlhqYizgDZYldd094PV6kSWvsDoMQO34IGu2kDr/C5DZGdOU3f29z8rRIQUUi2HQzcO1fiHVzsSatBxwktR83hC+fwh61mMAKo7sGm39P0BmTX1/GcHhoSJGgWnTT7C+5uUmrAS87OI9vDbgAOvsLIyNT7O+X+4GyAr2YJeP9i7oBv+8nxEH7gbIrEeT5IazhX7WZiH2LDdYsgqgzjJuAa+LXQbLr261QIP9pgOcFuET5s+1AFpnpnkI3wDGtQC6AvN+VggY0rnS4NUEhSfNhtu2tVghA05B6IPKstLgvwECiB5Fj7Q5BQAAAABJRU5ErkJggg==",shadowSize: [14, 24],});\
		var gcarch = L.icon({iconUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAMAAADW3miqAAACr1BMVEUAAAAAAAAAAAAAAABVVVVAQEA7Ozs8PDw6Ojo4ODg2NjY9PT04ODg8PDw7Ozs6Ojo5OTk+Pj44ODg5OTk4ODg3Nzc6Ojo5OTk8PDw4ODg3Nzc3NzdHR0dISEhLS0tOTk5LS0tMTExNTU1NTU1QUFBPT09MTExLS0tQUFBRUVFRUVFQUFBKSkpLS0tLS0tLS0tLS0tMTExNTU1NTU1MTExOTk5OTk5PT09QUFBNTU1OTk5OTk5RUVFSUlJRUVFSUlJRUVFzc3N0dHRJSUl1dXVISEhvb29wcHBycnJxcXFzc3N0dHSMjIyOjo6Pj4+FhYWOjo6QkJCHh4eIiIiMjIyhoaGkpKSmpqalpaWnp6ehoaGioqKkpKSlpaWmpqaoqKipqamoqKjBwcHDw8PExMRycnKQo62QpK6RpK6Rpa+Spa+SprCUp7GWlpaWqLGarLWjs7yjtLymtb2nU1enVFioUFSoUVWouMCpT1OpuMCpucCqqqqqucGrUlarusGtvMOuvcSwVVixvcSxvsWyWFuyvsWyv8azMjOzNDWzv8Wzv8a0MzS0MzW2W122w8q3HBy3xMq3xMu4w8q4xMu5xsy6X2G7ZWe/v7+/ys/AYmTAZWbBZGbBzNLCzdLCzdPDzdPDztPEz9TFbW7HaWvHbW3Ib3DI0tfNb3DNzc3Ozs7Q2d3RcXHR2t7ScXHS2t7Tc3PTdHTT29/Ud3fUeXnW1tbX19fY2NjZ2dna2tra4eTc4uXd4+be5Ofg5ujg5unh5unh5+ni5+rj6Ork5OTk6evl5eXm5ubn5+fn6+3o6Ojo7O7p2Njp2Nnp7e/q2drr7e/s7vDs8PHu8fLv8vTy9PXy9fbz6+zz9fb07O307e307e709fb17e72+Pj5+vv7/Pz+/f3+/v7+/////v7///8oNpcLAAAAZnRSTlMAAQIDAwwNHh8gNDY3Nzg5Ojo7P0BBQkNEUlNUb3KVl5ibm5ymp6ipqaqrrK2uwcLDw8PExc7Pz8/Q0NHi4uPj5efn6Ojp6+vr7Ozs7Ozs7e3t7u7x8vLy8/P09PT09/j4+fv7+/0mai7jAAAAAWJLR0TkL2I7KQAAAoNJREFUOMtjYBhIwMghICkpwMGIR4m4tr2TX2Kin4uNligOJYLWwdufQMG2ICs+LEpYlL1OPnlyZd2cyZPnrLv65MlxTwUmdDVsBuFPnuwvT4eCyv1PnsQas6KZY5Ly5FZzOhJovfYk2RjVLMXIJ2c6itMQatJK208/iVVCVsPv/eROT38/QlVaaX9/97Unnsiutzj5pKmiv7+/DKwqpy6jBMgpbX1yzBKhRiLoyd70NIiqzJqN9x4vBalJS9//JEgErkh7xxOgv8CqZt1+8uTxZoia9KonWzXgcWH/8ArImqKZQMkND8BqVjeBRK4+tIPFEKfTkzUgofsP1gKlN60HEusfPJoPFFn3xIkdqkgo8MkckKJ7T8CqwGqePFwFFJn3xJcfqkg64UkfSNGlPVBV6x/cXbavEigy8Um8FFSRVPyTCSBFF/N3gd3Tv3xGTvr1HKDI5CdxkrCgDHgyF6TobGHWIoh1ZWn1p0AiC5748KA5vOF8LVBBCygklpyoSwc73BHmcEbbh9fBcTENKD01La0RHvbXEUHAoLn9CdCZaaC4mD2pYOeFXqiqmidbVOAhLhb05BBEzeILRy5PyYTGUPrBJ/7CiMgzP/ykDRynebsXZqdDY6is68lRM6RUwOv15EY3JL6gSQWoquPWEzdu5ASlEPHkdHspcqKr6Dj3JFoeJWUyGSY/udaKnHw7bz5J0kPLCqz6YU+eHKiCKak5+ORJjBErenZhUvA4/uTJ9Y1zJ0+eu/H6kydH3eWYsOQ8XrOgrQ8hefPhVn9TLhx5WETDITW3ujo31UFVGE9pwOy6Yvr0lc7M+IsV2ZAnT0JkCJU9OqFRuoyESigWdTUWdDEAIl9nPl/W5sYAAAAASUVORK5CYII=",\
		iconSize: [24, 24],iconAnchor: [12,24],shadowUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAMAAADW3miqAAACr1BMVEUAAAAAAAAAAAAAAABVVVVAQEA7Ozs8PDw6Ojo4ODg2NjY9PT04ODg8PDw7Ozs6Ojo5OTk+Pj44ODg5OTk4ODg3Nzc6Ojo5OTk8PDw4ODg3Nzc3NzdHR0dISEhLS0tOTk5LS0tMTExNTU1NTU1QUFBPT09MTExLS0tQUFBRUVFRUVFQUFBKSkpLS0tLS0tLS0tLS0tMTExNTU1NTU1MTExOTk5OTk5PT09QUFBNTU1OTk5OTk5RUVFSUlJRUVFSUlJRUVFzc3N0dHRJSUl1dXVISEhvb29wcHBycnJxcXFzc3N0dHSMjIyOjo6Pj4+FhYWOjo6QkJCHh4eIiIiMjIyhoaGkpKSmpqalpaWnp6ehoaGioqKkpKSlpaWmpqaoqKipqamoqKjBwcHDw8PExMRycnKQo62QpK6RpK6Rpa+Spa+SprCUp7GWlpaWqLGarLWjs7yjtLymtb2nU1enVFioUFSoUVWouMCpT1OpuMCpucCqqqqqucGrUlarusGtvMOuvcSwVVixvcSxvsWyWFuyvsWyv8azMjOzNDWzv8Wzv8a0MzS0MzW2W122w8q3HBy3xMq3xMu4w8q4xMu5xsy6X2G7ZWe/v7+/ys/AYmTAZWbBZGbBzNLCzdLCzdPDzdPDztPEz9TFbW7HaWvHbW3Ib3DI0tfNb3DNzc3Ozs7Q2d3RcXHR2t7ScXHS2t7Tc3PTdHTT29/Ud3fUeXnW1tbX19fY2NjZ2dna2tra4eTc4uXd4+be5Ofg5ujg5unh5unh5+ni5+rj6Ork5OTk6evl5eXm5ubn5+fn6+3o6Ojo7O7p2Njp2Nnp7e/q2drr7e/s7vDs8PHu8fLv8vTy9PXy9fbz6+zz9fb07O307e307e709fb17e72+Pj5+vv7/Pz+/f3+/v7+/////v7///8oNpcLAAAAZnRSTlMAAQIDAwwNHh8gNDY3Nzg5Ojo7P0BBQkNEUlNUb3KVl5ibm5ymp6ipqaqrrK2uwcLDw8PExc7Pz8/Q0NHi4uPj5efn6Ojp6+vr7Ozs7Ozs7e3t7u7x8vLy8/P09PT09/j4+fv7+/0mai7jAAAAAWJLR0TkL2I7KQAAAoNJREFUOMtjYBhIwMghICkpwMGIR4m4tr2TX2Kin4uNligOJYLWwdufQMG2ICs+LEpYlL1OPnlyZd2cyZPnrLv65MlxTwUmdDVsBuFPnuwvT4eCyv1PnsQas6KZY5Ly5FZzOhJovfYk2RjVLMXIJ2c6itMQatJK208/iVVCVsPv/eROT38/QlVaaX9/97Unnsiutzj5pKmiv7+/DKwqpy6jBMgpbX1yzBKhRiLoyd70NIiqzJqN9x4vBalJS9//JEgErkh7xxOgv8CqZt1+8uTxZoia9KonWzXgcWH/8ArImqKZQMkND8BqVjeBRK4+tIPFEKfTkzUgofsP1gKlN60HEusfPJoPFFn3xIkdqkgo8MkckKJ7T8CqwGqePFwFFJn3xJcfqkg64UkfSNGlPVBV6x/cXbavEigy8Um8FFSRVPyTCSBFF/N3gd3Tv3xGTvr1HKDI5CdxkrCgDHgyF6TobGHWIoh1ZWn1p0AiC5748KA5vOF8LVBBCygklpyoSwc73BHmcEbbh9fBcTENKD01La0RHvbXEUHAoLn9CdCZaaC4mD2pYOeFXqiqmidbVOAhLhb05BBEzeILRy5PyYTGUPrBJ/7CiMgzP/ykDRynebsXZqdDY6is68lRM6RUwOv15EY3JL6gSQWoquPWEzdu5ASlEPHkdHspcqKr6Dj3JFoeJWUyGSY/udaKnHw7bz5J0kPLCqz6YU+eHKiCKak5+ORJjBErenZhUvA4/uTJ9Y1zJ0+eu/H6kydH3eWYsOQ8XrOgrQ8hefPhVn9TLhx5WETDITW3ujo31UFVGE9pwOy6Yvr0lc7M+IsV2ZAnT0JkCJU9OqFRuoyESigWdTUWdDEAIl9nPl/W5sYAAAAASUVORK5CYII=",shadowSize: [24, 24],});\
		var puzzle = L.icon({iconUrl: "http://www.geocaching.com/images/wpttypes/sm/puzzle.jpg",\
		iconSize: [16, 16],shadowUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAdCAQAAAD8mq+EAAABOklEQVQ4y+3V7U7CMBgF4NNKgyAYFUSjEYPeEsZrNHpLatBgFPkw+IFkY/O0XQRtwWT965q3LUkfTsO2IrB4Cfx9pe5ikfViJUvnXHwzAWmgXEETgxND03nWGlvB9HIpnLHFpk8ttVChiHWW4tzdtk6bIcIUn6xIY0t1XgkVbLJKxNJDE4IJ3jBmTXS2/f4C06qose2QF51cmzklG2LA9sp5LMwinbmNPRxgH1so87NLY3zgBY94wBNGOtdShQ0mHuKYuMZNKw+NuNEBYQddju+I7O1QXF7HEVqsuqHyF00M7eMet6w+5wt0l5ktNDlWcO65NRdc/ow70g7HH7RBdsJqcH7moZdc3iO9YfVceprRtodeZfT6n+b8hQPua66nKeAZDnhzcr+vAadE0NkUcCIGncMBp3+u/5wv7sf1TWI1cMgAAAAASUVORK5CYII=",shadowSize: [16, 16],});\
		var trailhead = L.icon({iconUrl: "http://www.geocaching.com/images/wpttypes/sm/trailhead.jpg",\
		iconSize: [16, 16],shadowUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAdCAQAAAD8mq+EAAABOklEQVQ4y+3V7U7CMBgF4NNKgyAYFUSjEYPeEsZrNHpLatBgFPkw+IFkY/O0XQRtwWT965q3LUkfTsO2IrB4Cfx9pe5ikfViJUvnXHwzAWmgXEETgxND03nWGlvB9HIpnLHFpk8ttVChiHWW4tzdtk6bIcIUn6xIY0t1XgkVbLJKxNJDE4IJ3jBmTXS2/f4C06qose2QF51cmzklG2LA9sp5LMwinbmNPRxgH1so87NLY3zgBY94wBNGOtdShQ0mHuKYuMZNKw+NuNEBYQddju+I7O1QXF7HEVqsuqHyF00M7eMet6w+5wt0l5ktNDlWcO65NRdc/ow70g7HH7RBdsJqcH7moZdc3iO9YfVceprRtodeZfT6n+b8hQPua66nKeAZDnhzcr+vAadE0NkUcCIGncMBp3+u/5wv7sf1TWI1cMgAAAAASUVORK5CYII=",shadowSize: [16, 16],});\
		var blueflag = L.icon({iconUrl: "http://galeria.geocaching-sk.info/pic/blueflag.png",\
		iconSize: [16, 16],shadowUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAdCAQAAAD8mq+EAAABOklEQVQ4y+3V7U7CMBgF4NNKgyAYFUSjEYPeEsZrNHpLatBgFPkw+IFkY/O0XQRtwWT965q3LUkfTsO2IrB4Cfx9pe5ikfViJUvnXHwzAWmgXEETgxND03nWGlvB9HIpnLHFpk8ttVChiHWW4tzdtk6bIcIUn6xIY0t1XgkVbLJKxNJDE4IJ3jBmTXS2/f4C06qose2QF51cmzklG2LA9sp5LMwinbmNPRxgH1so87NLY3zgBY94wBNGOtdShQ0mHuKYuMZNKw+NuNEBYQddju+I7O1QXF7HEVqsuqHyF00M7eMet6w+5wt0l5ktNDlWcO65NRdc/ow70g7HH7RBdsJqcH7moZdc3iO9YfVceprRtodeZfT6n+b8hQPua66nKeAZDnhzcr+vAadE0NkUcCIGncMBp3+u/5wv7sf1TWI1cMgAAAAASUVORK5CYII=",shadowSize: [16, 16],});\
		var fix2 = L.icon({iconUrl: "http://galeria.geocaching-sk.info/pic/fix2.png",\
		iconSize: [16, 16],shadowUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAdCAQAAAD8mq+EAAABOklEQVQ4y+3V7U7CMBgF4NNKgyAYFUSjEYPeEsZrNHpLatBgFPkw+IFkY/O0XQRtwWT965q3LUkfTsO2IrB4Cfx9pe5ikfViJUvnXHwzAWmgXEETgxND03nWGlvB9HIpnLHFpk8ttVChiHWW4tzdtk6bIcIUn6xIY0t1XgkVbLJKxNJDE4IJ3jBmTXS2/f4C06qose2QF51cmzklG2LA9sp5LMwinbmNPRxgH1so87NLY3zgBY94wBNGOtdShQ0mHuKYuMZNKw+NuNEBYQddju+I7O1QXF7HEVqsuqHyF00M7eMet6w+5wt0l5ktNDlWcO65NRdc/ow70g7HH7RBdsJqcH7moZdc3iO9YfVceprRtodeZfT6n+b8hQPua66nKeAZDnhzcr+vAadE0NkUcCIGncMBp3+u/5wv7sf1TWI1cMgAAAAASUVORK5CYII=",shadowSize: [16, 16],});\
		var fix3 = L.icon({iconUrl: "http://galeria.geocaching-sk.info/pic/fix3.png",\
		iconSize: [16, 16],shadowUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAdCAQAAAD8mq+EAAABOklEQVQ4y+3V7U7CMBgF4NNKgyAYFUSjEYPeEsZrNHpLatBgFPkw+IFkY/O0XQRtwWT965q3LUkfTsO2IrB4Cfx9pe5ikfViJUvnXHwzAWmgXEETgxND03nWGlvB9HIpnLHFpk8ttVChiHWW4tzdtk6bIcIUn6xIY0t1XgkVbLJKxNJDE4IJ3jBmTXS2/f4C06qose2QF51cmzklG2LA9sp5LMwinbmNPRxgH1so87NLY3zgBY94wBNGOtdShQ0mHuKYuMZNKw+NuNEBYQddju+I7O1QXF7HEVqsuqHyF00M7eMet6w+5wt0l5ktNDlWcO65NRdc/ow70g7HH7RBdsJqcH7moZdc3iO9YfVceprRtodeZfT6n+b8hQPua66nKeAZDnhzcr+vAadE0NkUcCIGncMBp3+u/5wv7sf1TWI1cMgAAAAASUVORK5CYII=",shadowSize: [16, 16],});\
		var virtual = L.icon({iconUrl: "https://www.geocaching.com/images/wpttypes/pins/218.png",\
		iconSize: [16, 16],shadowUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAdCAQAAAD8mq+EAAABOklEQVQ4y+3V7U7CMBgF4NNKgyAYFUSjEYPeEsZrNHpLatBgFPkw+IFkY/O0XQRtwWT965q3LUkfTsO2IrB4Cfx9pe5ikfViJUvnXHwzAWmgXEETgxND03nWGlvB9HIpnLHFpk8ttVChiHWW4tzdtk6bIcIUn6xIY0t1XgkVbLJKxNJDE4IJ3jBmTXS2/f4C06qose2QF51cmzklG2LA9sp5LMwinbmNPRxgH1so87NLY3zgBY94wBNGOtdShQ0mHuKYuMZNKw+NuNEBYQddju+I7O1QXF7HEVqsuqHyF00M7eMet6w+5wt0l5ktNDlWcO65NRdc/ow70g7HH7RBdsJqcH7moZdc3iO9YfVceprRtodeZfT6n+b8hQPua66nKeAZDnhzcr+vAadE0NkUcCIGncMBp3+u/5wv7sf1TWI1cMgAAAAASUVORK5CYII=",shadowSize: [16, 16],});\
		var reference = L.icon({iconUrl: "https://www.geocaching.com/images/wpttypes/pins/452.png",\
		iconSize: [16, 16],shadowUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAdCAQAAAD8mq+EAAABOklEQVQ4y+3V7U7CMBgF4NNKgyAYFUSjEYPeEsZrNHpLatBgFPkw+IFkY/O0XQRtwWT965q3LUkfTsO2IrB4Cfx9pe5ikfViJUvnXHwzAWmgXEETgxND03nWGlvB9HIpnLHFpk8ttVChiHWW4tzdtk6bIcIUn6xIY0t1XgkVbLJKxNJDE4IJ3jBmTXS2/f4C06qose2QF51cmzklG2LA9sp5LMwinbmNPRxgH1so87NLY3zgBY94wBNGOtdShQ0mHuKYuMZNKw+NuNEBYQddju+I7O1QXF7HEVqsuqHyF00M7eMet6w+5wt0l5ktNDlWcO65NRdc/ow70g7HH7RBdsJqcH7moZdc3iO9YfVceprRtodeZfT6n+b8hQPua66nKeAZDnhzcr+vAadE0NkUcCIGncMBp3+u/5wv7sf1TWI1cMgAAAAASUVORK5CYII=",shadowSize: [16, 16],});\
		var coordinateoverride = L.icon({iconUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAAAXCAYAAAAYyi9XAAAALHRFWHRDcmVhdGlvbiBUaW1lAFRodSAxNyBNYXkgMjAxMiAyMjoxMjo1MiAtMDAwMP%2F5zBkAAAAHdElNRQfcBREVNTVnAq5wAAAACXBIWXMAAAsSAAALEgHS3X78AAAABGdBTUEAALGPC%2FxhBQAAAnRJREFUeNq9lMlrFEEUh19VdU3P1j0koujFmYzE4B8gCaIXTx6SgODFBUTw4lkv4kHxKuLFs4JHEZQkF0GM%2B4KIATHE4DATBMmiSetktq7NVxM7DB4n03nQdHdtv%2FreRmAbrFAo%2BM4e55477Oad7RAkaTKmq%2FqYrMgE3Q464pJL7kGXAQMRu6ClAwEHUodSjlpUzVhdGtElR5IU6QC%2FF2IltHSEkP3%2BOZ833zQFSZKnsRFGdJnxjOPsciD8GoZA4X5shG06Rga9k14inAtxANbkgvwci%2BAm3WiG830c6k%2Fqkqboq0qlUo3FpZ10%2Bo%2BG1kxLgoRJO9dzwn90F%2F2zvsMHuY0d6HXdkEvyWSyClo56tJA9kXUxbtB43tCEk3nTMMt2vmuXIkkaXz4%2BSxgb00nnnfZSbDcDFIHmBywHTqZwjexaEA9m2Ixv6po%2BjkRvi35xAmP1kqTI4TbdeDZp14mSAPldShR%2BHO3tShBvq4peccY0zXm2k42xPDuCBwuMFfPObNBZw2SxrxVs3HNbErSGh9xl%2FWxEr%2BlT%2Fdf6d%2FA8B13Xmu%2Fl7bwwytj4CZqmL0qVUjXa13XSIGWoVtVlY8xscCOwbQsSQwmKbm3Pqx%2FKEiq82GTnvi1lKYoumqq5IMqiGtwOlBFmcy6cbXeXmvqlXvdM0Fr5W%2FkdGLi6%2FmBd1x7VNgZR13YXkiCf8G%2Bxp4LWMFnu0CSdCG4FYbvQA%2BwuH1sS4zgZlUxkrBeCQRCInJt7DxxGxbzIsT7GalO1lvltrgSrwXLnWtILwcgGhgaOYpE%2FpH3Uw5L5olbUMBLWe%2B7SyEzLTOOJ19VP1cLmPf2%2FmLW%2FylgqETpxl%2BsAAAAASUVORK5CYII%3D",\
		iconSize: [16, 16],shadowUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAdCAQAAAD8mq+EAAABOklEQVQ4y+3V7U7CMBgF4NNKgyAYFUSjEYPeEsZrNHpLatBgFPkw+IFkY/O0XQRtwWT965q3LUkfTsO2IrB4Cfx9pe5ikfViJUvnXHwzAWmgXEETgxND03nWGlvB9HIpnLHFpk8ttVChiHWW4tzdtk6bIcIUn6xIY0t1XgkVbLJKxNJDE4IJ3jBmTXS2/f4C06qose2QF51cmzklG2LA9sp5LMwinbmNPRxgH1so87NLY3zgBY94wBNGOtdShQ0mHuKYuMZNKw+NuNEBYQddju+I7O1QXF7HEVqsuqHyF00M7eMet6w+5wt0l5ktNDlWcO65NRdc/ow70g7HH7RBdsJqcH7moZdc3iO9YfVceprRtodeZfT6n+b8hQPua66nKeAZDnhzcr+vAadE0NkUcCIGncMBp3+u/5wv7sf1TWI1cMgAAAAASUVORK5CYII=",shadowSize: [16, 16],});\
		var tree = L.icon({iconUrl: "https://josm.openstreetmap.de/export/10565/josm/trunk/images/icons/natural_tree.n.16.png",\
		iconSize: [16, 16],shadowUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAdCAQAAAD8mq+EAAABOklEQVQ4y+3V7U7CMBgF4NNKgyAYFUSjEYPeEsZrNHpLatBgFPkw+IFkY/O0XQRtwWT965q3LUkfTsO2IrB4Cfx9pe5ikfViJUvnXHwzAWmgXEETgxND03nWGlvB9HIpnLHFpk8ttVChiHWW4tzdtk6bIcIUn6xIY0t1XgkVbLJKxNJDE4IJ3jBmTXS2/f4C06qose2QF51cmzklG2LA9sp5LMwinbmNPRxgH1so87NLY3zgBY94wBNGOtdShQ0mHuKYuMZNKw+NuNEBYQddju+I7O1QXF7HEVqsuqHyF00M7eMet6w+5wt0l5ktNDlWcO65NRdc/ow70g7HH7RBdsJqcH7moZdc3iO9YfVceprRtodeZfT6n+b8hQPua66nKeAZDnhzcr+vAadE0NkUcCIGncMBp3+u/5wv7sf1TWI1cMgAAAAASUVORK5CYII=",shadowSize: [16, 16],});\
		var hotel = L.icon({iconUrl: "https://github.com/openstreetmap/map-icons/blob/master/square.small/accommodation/hotel.png?raw=true",\
		iconSize: [16, 16],shadowUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAdCAQAAAD8mq+EAAABOklEQVQ4y+3V7U7CMBgF4NNKgyAYFUSjEYPeEsZrNHpLatBgFPkw+IFkY/O0XQRtwWT965q3LUkfTsO2IrB4Cfx9pe5ikfViJUvnXHwzAWmgXEETgxND03nWGlvB9HIpnLHFpk8ttVChiHWW4tzdtk6bIcIUn6xIY0t1XgkVbLJKxNJDE4IJ3jBmTXS2/f4C06qose2QF51cmzklG2LA9sp5LMwinbmNPRxgH1so87NLY3zgBY94wBNGOtdShQ0mHuKYuMZNKw+NuNEBYQddju+I7O1QXF7HEVqsuqHyF00M7eMet6w+5wt0l5ktNDlWcO65NRdc/ow70g7HH7RBdsJqcH7moZdc3iO9YfVceprRtodeZfT6n+b8hQPua66nKeAZDnhzcr+vAadE0NkUcCIGncMBp3+u/5wv7sf1TWI1cMgAAAAASUVORK5CYII=",shadowSize: [16, 16],});\
		var information = L.icon({iconUrl: "https://github.com/openstreetmap/map-icons/blob/master/square.small/misc/information.png?raw=true",\
		iconSize: [16, 16],shadowUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAdCAQAAAD8mq+EAAABOklEQVQ4y+3V7U7CMBgF4NNKgyAYFUSjEYPeEsZrNHpLatBgFPkw+IFkY/O0XQRtwWT965q3LUkfTsO2IrB4Cfx9pe5ikfViJUvnXHwzAWmgXEETgxND03nWGlvB9HIpnLHFpk8ttVChiHWW4tzdtk6bIcIUn6xIY0t1XgkVbLJKxNJDE4IJ3jBmTXS2/f4C06qose2QF51cmzklG2LA9sp5LMwinbmNPRxgH1so87NLY3zgBY94wBNGOtdShQ0mHuKYuMZNKw+NuNEBYQddju+I7O1QXF7HEVqsuqHyF00M7eMet6w+5wt0l5ktNDlWcO65NRdc/ow70g7HH7RBdsJqcH7moZdc3iO9YfVceprRtodeZfT6n+b8hQPua66nKeAZDnhzcr+vAadE0NkUcCIGncMBp3+u/5wv7sf1TWI1cMgAAAAASUVORK5CYII=",shadowSize: [16, 16],});\
		var viewpoint = L.icon({iconUrl: "https://github.com/openstreetmap/map-icons/blob/master/square.small/sightseeing/viewpoint.png?raw=true",\
		iconSize: [16, 16],shadowUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAdCAQAAAD8mq+EAAABOklEQVQ4y+3V7U7CMBgF4NNKgyAYFUSjEYPeEsZrNHpLatBgFPkw+IFkY/O0XQRtwWT965q3LUkfTsO2IrB4Cfx9pe5ikfViJUvnXHwzAWmgXEETgxND03nWGlvB9HIpnLHFpk8ttVChiHWW4tzdtk6bIcIUn6xIY0t1XgkVbLJKxNJDE4IJ3jBmTXS2/f4C06qose2QF51cmzklG2LA9sp5LMwinbmNPRxgH1so87NLY3zgBY94wBNGOtdShQ0mHuKYuMZNKw+NuNEBYQddju+I7O1QXF7HEVqsuqHyF00M7eMet6w+5wt0l5ktNDlWcO65NRdc/ow70g7HH7RBdsJqcH7moZdc3iO9YfVceprRtodeZfT6n+b8hQPua66nKeAZDnhzcr+vAadE0NkUcCIGncMBp3+u/5wv7sf1TWI1cMgAAAAASUVORK5CYII=",shadowSize: [16, 16],});\
		var peak = L.icon({iconUrl: "https://github.com/openstreetmap/map-icons/blob/master/square.small/place/peak.png?raw=true",\
		iconSize: [16, 16],shadowUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAdCAQAAAD8mq+EAAABOklEQVQ4y+3V7U7CMBgF4NNKgyAYFUSjEYPeEsZrNHpLatBgFPkw+IFkY/O0XQRtwWT965q3LUkfTsO2IrB4Cfx9pe5ikfViJUvnXHwzAWmgXEETgxND03nWGlvB9HIpnLHFpk8ttVChiHWW4tzdtk6bIcIUn6xIY0t1XgkVbLJKxNJDE4IJ3jBmTXS2/f4C06qose2QF51cmzklG2LA9sp5LMwinbmNPRxgH1so87NLY3zgBY94wBNGOtdShQ0mHuKYuMZNKw+NuNEBYQddju+I7O1QXF7HEVqsuqHyF00M7eMet6w+5wt0l5ktNDlWcO65NRdc/ow70g7HH7RBdsJqcH7moZdc3iO9YfVceprRtodeZfT6n+b8hQPua66nKeAZDnhzcr+vAadE0NkUcCIGncMBp3+u/5wv7sf1TWI1cMgAAAAASUVORK5CYII=",shadowSize: [16, 16],});\
		var bicycle = L.icon({iconUrl: "https://github.com/openstreetmap/map-icons/blob/master/square.small/sport/bicycle.png?raw=true",\
		iconSize: [16, 16],shadowUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAdCAQAAAD8mq+EAAABOklEQVQ4y+3V7U7CMBgF4NNKgyAYFUSjEYPeEsZrNHpLatBgFPkw+IFkY/O0XQRtwWT965q3LUkfTsO2IrB4Cfx9pe5ikfViJUvnXHwzAWmgXEETgxND03nWGlvB9HIpnLHFpk8ttVChiHWW4tzdtk6bIcIUn6xIY0t1XgkVbLJKxNJDE4IJ3jBmTXS2/f4C06qose2QF51cmzklG2LA9sp5LMwinbmNPRxgH1so87NLY3zgBY94wBNGOtdShQ0mHuKYuMZNKw+NuNEBYQddju+I7O1QXF7HEVqsuqHyF00M7eMet6w+5wt0l5ktNDlWcO65NRdc/ow70g7HH7RBdsJqcH7moZdc3iO9YfVceprRtodeZfT6n+b8hQPua66nKeAZDnhzcr+vAadE0NkUcCIGncMBp3+u/5wv7sf1TWI1cMgAAAAASUVORK5CYII=",shadowSize: [16, 16],});\
		var korona = L.icon({iconUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAABnRSTlMA/wD/AP83WBt9AAAACXBIWXMAAC4jAAAuIwF4pT92AAACW0lEQVQokWVSS0wTURS98ylQtFIo42dAGkGBOpoYjAuJgaiNIWJ0o6kxUVlRQk0l3WhFY4IoOxOMNR3YGGGDG6JxgcQmbiwJRuJnJm1TfgUyakasZtqBdNr3XEwdaLird/LOeffkvENgjGHLeHr9ABB4OLD1igQAURR5nt+sTKhKQlUMiDHmeV4Uxbygjw8MZldHRkcNhqSmJDVlQH54eDC72scHAIDAGIui2P3oQfGV80c/xZscB1+8fzfrqAGA/dGla63O6a9fxiFVvfgzcPsux3GE7kSWZaffR144rS5K5L5GLYMBwFQEaCFWamdzr0OhgccMw+QtAQDDMK5aB8pBrqohvSit3LmXnl9K/c3kqhoQgsu1Dp29IQCAsJTI0DtSyTRts1lONJurdmufZ5LjrzK0JSwlDBrt6fUnVEVaS60dOqBlMC1LSjxucToRQa3HYtkcrP/4PddY09TVwZq320stGxv0UWcXtG1WJRQiabLc5So7dZKqqNhMIIz4z91wz7Wd+T48oiX/lJ9to6zW9UiEOnKsjDHXTUy+ecrnLRnS46x9OatUXr+KEEZZtDb1QQlPsa0tRVmlmbUX/LQe68v5CEkCtRwtLiHpIsrS2mK/f4tajpIUMTYfkWW5oBqXfN70Hpvz42w/W1838dYkRU1StG5isp+tv1myU92766LPq1eDwBi7vN3fGqq9psquzk79mSZ3BwDM8M/z1RgaGtR+HY6tjD15BhhjQRCCwSBCCP+f9h5Pe4/HgAihYDAoCALGmAYAjuM4jtucnb3UUhAlQbjdbv38D6sZIyqU4Ab3AAAAAElFTkSuQmCC",\
		iconSize: [16, 16],shadowUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAdCAQAAAD8mq+EAAABOklEQVQ4y+3V7U7CMBgF4NNKgyAYFUSjEYPeEsZrNHpLatBgFPkw+IFkY/O0XQRtwWT965q3LUkfTsO2IrB4Cfx9pe5ikfViJUvnXHwzAWmgXEETgxND03nWGlvB9HIpnLHFpk8ttVChiHWW4tzdtk6bIcIUn6xIY0t1XgkVbLJKxNJDE4IJ3jBmTXS2/f4C06qose2QF51cmzklG2LA9sp5LMwinbmNPRxgH1so87NLY3zgBY94wBNGOtdShQ0mHuKYuMZNKw+NuNEBYQddju+I7O1QXF7HEVqsuqHyF00M7eMet6w+5wt0l5ktNDlWcO65NRdc/ow70g7HH7RBdsJqcH7moZdc3iO9YfVceprRtodeZfT6n+b8hQPua66nKeAZDnhzcr+vAadE0NkUcCIGncMBp3+u/5wv7sf1TWI1cMgAAAAASUVORK5CYII=",shadowSize: [16, 16],});\
		var hunting = L.icon({iconUrl: "https://github.com/openstreetmap/map-icons/blob/master/classic.small/hunting_stand.png?raw=true",\
		iconSize: [16, 16],shadowUrl: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAdCAQAAAD8mq+EAAABOklEQVQ4y+3V7U7CMBgF4NNKgyAYFUSjEYPeEsZrNHpLatBgFPkw+IFkY/O0XQRtwWT965q3LUkfTsO2IrB4Cfx9pe5ikfViJUvnXHwzAWmgXEETgxND03nWGlvB9HIpnLHFpk8ttVChiHWW4tzdtk6bIcIUn6xIY0t1XgkVbLJKxNJDE4IJ3jBmTXS2/f4C06qose2QF51cmzklG2LA9sp5LMwinbmNPRxgH1so87NLY3zgBY94wBNGOtdShQ0mHuKYuMZNKw+NuNEBYQddju+I7O1QXF7HEVqsuqHyF00M7eMet6w+5wt0l5ktNDlWcO65NRdc/ow70g7HH7RBdsJqcH7moZdc3iO9YfVceprRtodeZfT6n+b8hQPua66nKeAZDnhzcr+vAadE0NkUcCIGncMBp3+u/5wv7sf1TWI1cMgAAAAASUVORK5CYII=",shadowSize: [16, 16],});',
		'54386'
	);
}

function insertPage(div, src, title, back) {
	if (div && typeof src === 'string') {
		var d = document.createElement('div');
		d.id = div;
		d.title = title||'';
		d.innerHTML = ['<div><a href="#',back||'','" title="Close" class="gme-close-dialog">X</a><header>',d.title, '</header><div class="gme-modal-content">', src, '</div></div>'].join('');
		d.className = 'gme-modalDialog';
		document.documentElement.lastChild.appendChild(d);
	} else {
		console.warn("GME: insertPage not called with correct parameters.");
	}
}

function insertScript(src, id) {
//	console.log("GME: Inserting script: " + id);
//	console.debug(src);
	if (typeof src !== "string") { console.warn("GME: insertScript not called with string."); return; }
	var s = document.createElement("script");
	s.type = "text/javascript";
	s.text = src;
	if (id) {
		s.id = id;
	}
	document.documentElement.firstChild.appendChild(s);
	document.documentElement.firstChild.removeChild(s);
}

function unwrapFunction(fn) {
	var text;
	if (typeof fn === "function") {
		text = fn.toString();
		return text.slice(text.indexOf("{") + 1, text.lastIndexOf("}"));
	}
	return fn;
}

function xhr(e) {
	var node = document.getElementById("gme_jsonp_node"),
		callback = node.getAttribute("data-gme-callback"),
		url = node.text,
		details = {
            "method": "GET",
            "url": url,
            "onload": function(response) {
                var x = response.responseText,
                    call = x.match(/([a-zA-Z_$][0-9a-zA-Z_$]*)\s*\(/),
                    s;
                if (call && call.length === 2 && call[1] === callback) {
                    s = document.getElementById("gme_jsonp_node");
                    s.setAttribute("data-gme-callback", callback);
                    s.text = x.substring(x.indexOf("(")+1, x.lastIndexOf(")"));
                    document.dispatchEvent(new Event("GME_XHR_callback"));
                } else {
                    console.warn("Received: " + x);
                }
            }
        };
    if (gmeResources.env.xhr === 'GM4') {
        GM.xmlHttpRequest(details);
    } else {
        setTimeout(function() { GM_xmlhttpRequest(details);}, 0);
    }
}

//don't run on frames or iframes
if (window.top !== window.self) { return; }

if(!(typeof JSON === 'object' && typeof JSON.parse === 'function')) {
	console.error("Geocaching Map Enhancements requires a browser with JSON support.");
	return;
}

if(document.querySelector("head[data-gme-version]")) {
	console.error("Aborting: GME already running on page: " + document.location);
	return;
}
document.documentElement.firstChild.setAttribute("data-gme-version", gmeResources.parameters.version); 

for (i = 0; i < pageTests.length; i++) {
	if (pageTests[i][1].test(document.location.pathname)) {
		gmeResources.env.page = pageTests[i][0];
		break;
	}
}

try {
	if (window.localStorage !== undefined && window.localStorage !== null) { gmeResources.env.storage = true; }
} catch (e) {
	//Potential security exception
	console.warn("No localStorage capability - GME cannot set configuration");
}

if(gmeResources.env.storage) {
	var a, b, customJSON, GME_custom, paramsJSON, storedParams;
	// List of defunct tileUrls to remove from settings 
	var blacklist = [
		"https://ecn.t{s}.tiles.virtualearth.net/tiles/r{q}?g=737&productSet=mmOS",
		"https://ecn.t{s}.tiles.virtualearth.net/tiles/r{q}?g=864&productSet=mmCB",
		"https://otile{s}-s.mqcdn.com/tiles/1.0.0/osm/{z}/{x}/{y}.jpg",
		"https://otile{s}-s.mqcdn.com/tiles/1.0.0/sat/{z}/{x}/{y}.jpg"
	];

	try {
		paramsJSON = localStorage.getItem("GME_parameters");
		if (paramsJSON) {
			try {
				storedParams = JSON.parse(paramsJSON);
				if (storedParams.version !== gmeResources.parameters.version) {
					for (a in gmeResources.parameters) {
						if (gmeResources.parameters.hasOwnProperty(a)) {
							if (storedParams[a]===undefined){storedParams[a]=gmeResources.parameters[a];}
						}
					}
					alert("Geocaching Map Enhancements has been updated to v " + gmeResources.parameters.version + ". " + gmeResources.parameters.versionMsg);
					storedParams.version = gmeResources.parameters.version;
					localStorage.setItem("GME_parameters",JSON.stringify(storedParams));
				}
				if (typeof storedParams.maps === "string") {
					console.info("GME: Trying to fix corrupted map settings.");
					storedParams.maps = JSON.parse(storedParams.maps);
				}
				gmeResources.parameters = storedParams;
			} catch (e) {
				console.warn("GME: Could not parse stored configuration parameters.");
			}
		} 
		// Import old-style custom maps 
		customJSON = localStorage.getItem("GME_custom");
		if (customJSON) {
			console.info("GME: Found stored custom settings");
			try {
				GME_custom = JSON.parse(customJSON);
				if (GME_custom.maps && GME_custom.maps.length > 0) {
					gmeResources.parameters.maps = gmeResources.parameters.maps.concat(GME_custom.maps);
				}
				delete localStorage.GME_custom;
			} catch (e) {
				console.warn("GME: Could not parse stored custom maps.");
			} 
		}
		// Remove old-style builtin maps 
		if (gmeResources.parameters.includeMaps) {
			delete gmeResources.parameters.includeMaps;
		}
		if (gmeResources.parameters.excludeMaps) {
			for (a = gmeResources.parameters.excludeMaps.length - 1; a >= 0; a--) {
				for (b = gmeResources.parameters.maps.length -1; b >= 0; b--) {
					if (gmeResources.parameters.maps[b].alt === gmeResources.parameters.excludeMaps[a]) {
						gmeResources.parameters.maps[b].ignore = true;
					}
				}
			}
			delete gmeResources.parameters.excludeMaps;
		}

		// Remove broken map sources 
		for (a = gmeResources.parameters.maps.length - 1;  a >= 0; a--) {
			for(b = 0; b < blacklist.length; b++) {
				if (gmeResources.parameters.maps[a].tileUrl === blacklist[b]) {
					gmeResources.parameters.maps.splice(a,1);
				}
			}
		}

		localStorage.setItem("GME_parameters",JSON.stringify(gmeResources.parameters));
	} catch (e){
		console.error("GME: Bad Exception: " + e);
		// Potential security exception. Carry on with default parameters, but block localstorage 
		gmeResources.env.storage = false;
	}
}

document.addEventListener("GME_XHR_event", xhr);

if (!gmeResources.env.geolocation) {
	gmeResources.script.dist = function () { console.warn("GME: Geolocation not available"); };
}
if (!gmeResources.env.dragdrop) {
	gmeResources.script.drag = function () { console.warn("GME: Drag and Drop not available"); };
	gmeResources.script.drop = gmeResources.script.drag;
}


insertCSS(gmeResources.css.main); 
if(gmeResources.env.storage) {
	insertPage('GME_config', gmeResources.html.config, 'Configure GME v' + gmeResources.parameters.version);
	insertPage('GME_format', gmeResources.html.customInfo, 'Custom Mapsource Format', 'GME_config');
}

//	<bugfix>
	// Trixie treats jQuery Mobile dialogs as new page loads, resetting GME's functions
	if (window.GME !== undefined) { return; }
//	</bugfix>
L.NumberedDivIcon = L.Icon.extend({
	options: {
  	iconUrl: 'data:image/png;base64, ',
    number: '',
    shadowUrl: null,
    iconSize: new L.Point(25, 41),
		iconAnchor: new L.Point(13, 41),
		popupAnchor: new L.Point(0, -33),
		className: 'leaflet-div-icon'
	},
createIcon: function () {
    var div = document.createElement('div');
    var img = this._createImg(this.options['iconUrl']);
    var numdiv = document.createElement('div');
    numdiv.setAttribute("class", "number");
    numdiv.style.position = 'relative';  // pridanie pozície
    numdiv.style.top = '-41px';  // posunutie čísla
    numdiv.style.fontSize = '12px';  // veľkosť písma
    numdiv.style.width = '25px';  // šírka čísla
    numdiv.style.textAlign = 'center';  // zarovnanie čísla
    numdiv.innerHTML = this.options['number'] || '';
    div.appendChild(img);
    div.appendChild(numdiv);
    this._setIconStyles(div, 'icon');
    return div;
},
	createShadow: function () {
		return null;
	},
   _setIconStyles: function (img, name) {
        L.Icon.prototype._setIconStyles.call(this, img, name);
        img.style.background = 'transparent';  // nastavenie priesvitného pozadia
        img.style.border = 'none';  // odstránenie okraja
        img.style.opacity = '0.75';  // nastavenie priesvitnosti na 50%
    }
});
switch(gmeResources.env.page) {
	case "listing":
		// On a geocache listing
		if (!gmeResources.env.loggedin) {
			// Not logged in, so no maps or coordinates...
			console.log("GME: Couldn't detect log-in.  Exiting...");
			return;
		}
		if (gmeResources.env.dragdrop) { insertCSS(gmeResources.css.drag); }
		buildScript("GME_page_listing", "common", gmeResources.env.storage ? "config" : "", "map", "dist", "drag", "drop", "loadListing");
		break;
	case "seek":
		// On the Hide & Seek page
		target2 = document.querySelector(".SeekCacheWidget h4");
		targets = document.getElementsByTagName("h5");
		for (i = 0; i < targets.length; i++) {
			if (targets[i].innerHTML.match(/WGS84/)) {
				target = targets[i];
				break;
			}
		}
		
		if (target && target2) {
			var grDiv = document.createElement("div"), hereDiv = document.createElement("div");
			grDiv.innerHTML = '<h5>Ordnance Survey Grid Reference :</h5><dl><dt>Grid reference : </dt><dd><form name="grForm" id="grForm"><input type="text" class="Text EqualWidthInput" maxlength="50" size="15" name="grRef" id="grRef" placeholder="SU122422">&nbsp;<input type="submit" class="Button blockWithModalSpinner" name="submitGR" value="Go" id="grSub"></form></dd></dl><h5>Freeform coordinates</h5><dl><dt>Coordinates :</dt><dd><form name="coordForm" id="coordForm"><input type="text" class="Text EqualWidthInput" maxlength="50" size="15" name="gme_coords" id="gme_coords" placeholder="N 51Â° 10.683â€˛ W 001Â° 49.604â€˛"/>&nbsp;<input type="submit" class="Button blockWithModalSpinner" name="gme_coords_sub" value="Go" id="gme_coords_sub"/></form></dd></dl>';
			hereDiv.innerHTML = '<h4>Where you are...</h4><dl><dt>Use GeoLocation :</dt><dd><form name="hereForm" id="hereForm"><input type="submit" class="Button blockWithModalSpinner" name="GME_hereSub" value="Go" id="GME_hereSub"></form></dd></dl><h4>By keyword...</h4><dl><dt>Google search :</dt><dd><form name="googleForm" id="googleForm"><input type="text" class="Text EqualWidthInput" maxlength="50" size="15" name="gme_google" id="gme_google"/><input type="submit" class="Button blockWithModalSpinner" name="GME_googleSub" value="Go" id="GME_googleSub"></form></dd></dl>';
			target.parentNode.insertBefore(grDiv,target);
			target2.parentNode.insertBefore(hereDiv,target2);

			buildScript("GME_page_seek", "common", gmeResources.env.storage ? "config" : "", "osgb", "seek", "loadSeek");
		}
		break;
	case "track":
		// On a TB tracking map
		if (!gmeResources.env.loggedin) {
			// Not logged in, so no maps or coordinates...
			return;
		}
		buildScript("GME_page_track", "common", gmeResources.env.storage ? "config" : "", "map", "widget", "loadTrack");
		break;
	case "maps":
		// On a Geocaching Maps page
		// TODO: Detect if the Google Maps API is being used instead of Leaflet, and quit gracefully
//		if (document.querySelector("script[src*='//maps.googleapis.com/']")){
//			console.warn("Geocaching Map Enhancements requires Leaflet Maps to be enabled.");
//			return;
//	f	}

		// Check for click-thru cache data in URI
		var pop = location.search.match(/pop=([A-Za-z0-9+\/=]+)[\?&]?/);
		if (pop && pop.length === 2) {
			try {
				localStorage.setItem("GME_cache", pop[1]);
				location.search = location.search.replace(/&pop=[A-Za-z0-9+\/=]+[\?&]?/, "");
			} catch (e) {
				console.error(e + "GME couldn't decode click-through data: " + pop[1]);
			}
			return;
		}

		if (gmeResources.parameters.osgbSearch) {
			targets = document.getElementsByClassName("SearchBox");
			if (targets[0]) {
				targets[0].innerHTML = gmeResources.html.search;
			}
		}

		buildScript("GME_page_map", "common", gmeResources.env.storage ? "config" : "", "cssTransitionsFix", "map", "widget", "labels", "drop", gmeResources.parameters.osgbSearch ? "osgb" : "", "loadMap");
		break;
	case "type":
		buildScript("GME_page_type", "common", gmeResources.env.storage ? "config" : "", "map", "widget", "drop", "loadType");
		break;
	case "hide":
		buildScript("GME_page_hide", "common", gmeResources.env.storage ? "config" : "", "map", "widget", "drop", "loadHide");
		break;
	default:
		// Somewhere random on the main website
		if (gmeResources.env.storage) {
			buildScript("Generic config", "common", "config", "loadDefault");
		}
	}
function deleteLayerByPopup(link) {
    var popup = link.closest('.leaflet-popup-content');
    var popupText = popup.querySelector('b').textContent;
    MapSettings.Map.eachLayer(function (layer) {
        if (layer instanceof L.Polyline && layer.getPopup() && layer.getPopup().getContent().includes(popupText)) {
            MapSettings.Map.removeLayer(layer);
        }
    });
}

	
insertScript('var selectedPolylines=[];function exportSelectedLines(){if(selectedPolylines&&0!==selectedPolylines.length){var e=[];selectedPolylines.forEach((function(o){var t={id:o._leaflet_id,latlngs:o.getLatLngs(),color:o.options.color,weight:o.options.weight};e.push(t)}));var o=JSON.stringify(e),t=new XMLHttpRequest;t.open("POST","http://localhost:54386/receiveData",!0),t.setRequestHeader("Content-Type","application/json"),t.onload=function(){t.status>=200&&t.status<300?console.log(t.responseText):console.error("Error:",t.statusText)},t.onerror=function(){console.error("Request failed")},t.send(o)}else console.error("No selected polylines to export.")}function exportLineData(e){var o;console.log("exportLineData:",e),polylineGroup.eachLayer((function(t){t._leaflet_id===e&&(o=t,selectedPolylines.push(o))}))}var polylineGroup=L.featureGroup().addTo(MapSettings.Map);function handleExport(){console.log(selectedPolylines),exportSelectedLines()}function createPolyline(e,o){var t={color:o,dashArray:"10,8",weight:"2"},l={color:"#ff0000",dashArray:"10,8",weight:"4"},i=L.polyline(e,t);return i.on("click",(function(e){L.popup().setLatLng(e.latlng).setContent("<div>polyline id="+i._leaflet_id+\'</div><p><a href="#" onclick="exportLineData(\'+i._leaflet_id+\');return false;">Pridať do exportu</a></p><p><a href="#" onclick="removeLine(\'+i._leaflet_id+\');return false;">Vymazať čiaru</a></p><p><a href="#" onclick="toggleHighlight(\'+i._leaflet_id+\');return false;">Zvýrazniť/Obnoviť čiaru</a></p><p><a href="#" onclick="handleExport();return false;">Exportovať dáta</a></p>\').openOn(MapSettings.Map)})),polylineGroup.addLayer(i),i.highlight=function(){this.setStyle(l)},i.resetHighlight=function(){this.setStyle(t)},i.toggleHighlight=function(){this.options.weight===t.weight?this.highlight():this.resetHighlight()},i}function removeLine(e){polylineGroup.eachLayer((function(o){o._leaflet_id===e&&polylineGroup.removeLayer(o)}))}function exportHighlightedLines(){var e=[];highlightedLines.forEach((function(o){var t={id:o._leaflet_id,latlngs:o.getLatLngs(),color:o.options.color,weight:o.options.weight};e.push(t),console.log("exportHighlightedLines:"+o._leaflet_id)}));var o=JSON.stringify(e,null,2),t=new Blob([o],{type:"application/json"}),l=URL.createObjectURL(t),i=document.createElement("a");i.href=l,i.download="highlighted_lines.json",document.body.appendChild(i),i.click(),document.body.removeChild(i)}function toggleHighlight(e){polylineGroup.eachLayer((function(o){o._leaflet_id===e&&(o.toggleHighlight(),console.log("toggleHighlight:"+e))}))}var highlightedLines=[];function addToMyList(e){var o;polylineGroup.eachLayer((function(t){t._leaflet_id===e&&(o=t)})),o?(highlightedLines.push(o),console.log("Polyline added to My List:",o)):console.error("Polyline with ID "+e+" does not exist.")}');	
insertScript('function highlightMapCenter(lat, lon) {' +
' var crossIcon = L.divIcon({' +
'   html: "+", className: "highlight-cross", iconSize: [10, 10], iconAnchor: [0, 0]' +
' });' +
' var tempMarker = L.marker([lat, lon], { icon: crossIcon }).addTo(MapSettings.Map);' +
' setTimeout(function () { MapSettings.Map.removeLayer(tempMarker); }, 10000);' +
'}');

//==================================================================================================================  
  if(document.querySelector("#gc-header-root")){$("<div id='latlon' style='display:none;'>latitude,longitude</div>" ).insertAfter( $( "#gc-header-root" ) );};
  MapSettings.Map.on('mousemove', function(e) {var lls=e.latlng.lat.toFixed(6)+","+e.latlng.lng.toFixed(6);
  document.getElementById("latlon").innerHTML=lls;$(".gme-scale").html(lls);});$(".ToggleSidebar").css("width","5px");
  $("#scrollbar").css("padding","0 5px 0 5px");$(".Sidebar").css("padding","0 5px 10px 0");$(".Sidebar").css("width","360px");
  $(".leaflet-control-attribution.leaflet-control").hide();$("#search-map-cta")[0].innerHTML='<img src="https://icons.iconarchive.com/icons/martz90/circle-addon2/24/downloads-icon.png">';
  $("#search-map-cta")[0].title="Downloads";$("#search-map-cta").css("padding","6px");$(".ToggleSidebar").click();
  document.getElementById("gc-header-root").addEventListener("mouseup",function(){{ if ( $(".map-wrapper").css("top") > "74px" ){ $(".map-wrapper").css("top", "6px") } else { $(".map-wrapper").css("top", "80px") }; }});
  $(".leaflet-control-attribution.leaflet-control").hide();
  $("#search-map-cta")[0].title="Downloads";
  $("#search-map-cta").css("padding","6px");$(".ToggleSidebar").click();
  }());
  

function computeDistance(poly) {
    var total = 0;
    for (var i = 1; i < poly.length; i++) {
        total += poly[i - 1].distanceTo(poly[i]);
    }
    return Math.round(total);
}

function computeAscend(poly) {
    var total = 0;
    for (var i = 1; i < poly.length; i++) {
        var d = (poly[i].alt || 0) - (poly[i - 1].alt || 0);
        if (d > 0) total += d;
    }
    return Math.round(total);
}

function computeDescend(poly) {
    var total = 0;
//	debugger;
    for (var i = 1; i < poly.length; i++) {
        var d = (poly[i - 1].alt || 0) - (poly[i].alt || 0);
        if (d > 0) total += d;
    }
    return Math.round(total);
}

function flattenLatLngs(arr) {
    var result = [];
    for (var i = 0; i < arr.length; i++) {
        var item = arr[i];
        if (Array.isArray(item)) {
            result = result.concat(flattenLatLngs(item));
        } else {
            result.push(item);
        }
    }
    return result;
}

function flattenLatLngs(arr) {
    var result = [];
    for (var i = 0; i < arr.length; i++) {
        var item = arr[i];
        if (Array.isArray(item)) {
            result = result.concat(flattenLatLngs(item));
        } else {
            result.push(item);
        }
    }
    return result;
}
window.showAltitudeProfile = function(poly) {
    var data = poly._gpxinfo || {};
    var filename = data.filename;

    if (!filename) {
        alert("Chýba názov GPX súboru.");
        return;
    }

    var encodedFilename = encodeURIComponent(filename);
    var url = "http://localhost:54386/kml/altitude-gpx.html?gpx=" + encodedFilename;

    var win = window.open("", "_blank", "width=700,height=400,resizable=yes,scrollbars=yes,left=100,top=100");

    if (!win) {
        alert("Nepodarilo sa otvoriť nové okno.");
        return;
    }

    // IE-friendly oneskorené nastavenie URL
    var interval = setInterval(function () {
        try {
            if (win.document && win.document.readyState === "complete") {
                clearInterval(interval);
                win.location.href = url;
            }
        } catch (e) {
            clearInterval(interval);
            win.location.href = url;
        }
    }, 100);
};

window.drawAdvancedGPXPolylineFromText = function(gpxText, filename) {

  if (typeof MapSettings === "undefined" || !MapSettings.Map) {
    alert("MapSettings.Map nie je pripravená.");
    return;
  }

  if (!window.moziGoRoutes) window.moziGoRoutes = {};
  if (!window.moziGoMarkers) window.moziGoMarkers = [];

  function computeDistance(points) {
    var d = 0;
    for (var i = 1; i < points.length; i++) {
      d += points[i - 1].distanceTo(points[i]);
    }
    return d;
  }

  function computeAscend(points) {
    var sum = 0;
    for (var i = 1; i < points.length; i++) {
      var prev = points[i - 1].alt || 0;
      var curr = points[i].alt || 0;
      if (curr > prev) sum += (curr - prev);
    }
    return Math.round(sum);
  }

  function computeDescend(points) {
    var sum = 0;
    for (var i = 1; i < points.length; i++) {
      var prev = points[i - 1].alt || 0;
      var curr = points[i].alt || 0;
      if (curr < prev) sum += (prev - curr);
    }
    return Math.round(sum);
  }

  function parseGPX(text, filename) {
    var parser = new DOMParser();
    var xml = parser.parseFromString(text, "application/xml");

    // WPT body (additional points)
    var wpts = xml.getElementsByTagName("wpt");
    for (var i = 0; i < wpts.length; i++) {
      var wpt = wpts[i];
      var lat = parseFloat(wpt.getAttribute("lat"));
      var lon = parseFloat(wpt.getAttribute("lon"));
      var nameEl = wpt.getElementsByTagName("name")[0];
      var name = nameEl ? nameEl.textContent : "WPT " + i;

      var marker = L.marker([lat, lon], {
        icon: L.icon({
          iconUrl: "https://maps.google.com/mapfiles/ms/icons/ltblue-dot.png",
          iconSize: [16, 16],
          iconAnchor: [8, 8]
        }),
        title: name,
        clickable: false
      }).addTo(MapSettings.Map);

      window.moziGoMarkers.push(marker);
    }

    var trks = xml.getElementsByTagName("trk");

    for (var i = 0; i < trks.length; i++) {
      var trk = trks[i];
      var nameEl = trk.getElementsByTagName("name")[0];
      var descEl = trk.getElementsByTagName("desc")[0];

      var name = nameEl ? nameEl.textContent : "Track " + (i + 1);
      var desc = descEl ? descEl.textContent.trim() : "";

      var color = "#0000FF", dashArray = "", weight = 4;
      if (desc === "KORIDOR-L" || desc === "KORIDOR-R") {
        color = "#00AA00"; dashArray = "6,4"; weight = 3;
      }

      var segments = trk.getElementsByTagName("trkseg");
      for (var j = 0; j < segments.length; j++) {
        var seg = segments[j];
        var trkpts = seg.getElementsByTagName("trkpt");
        var poly = [];

        for (var k = 0; k < trkpts.length; k++) {
          var pt = trkpts[k];
          var lat = parseFloat(pt.getAttribute("lat"));
          var lon = parseFloat(pt.getAttribute("lon"));
          var eleEl = pt.getElementsByTagName("ele")[0];
          var ele = eleEl ? parseFloat(eleEl.textContent) : null;
          var point = L.latLng(lat, lon);
          if (ele !== null) point.alt = ele;
          poly.push(point);
        }

        var dist = computeDistance(poly);
        var ascend = computeAscend(poly);
        var descend = computeDescend(poly);

        var polyline = L.polyline(poly, {
          color: color,
          weight: weight,
          dashArray: dashArray
        }).addTo(MapSettings.Map);

        var startPoint = poly[0];
        var startMarker = L.marker(startPoint, {
          icon: L.icon({
            iconUrl: "https://maps.google.com/mapfiles/ms/icons/green-dot.png",
            iconSize: [20, 20],
            iconAnchor: [10, 20]
          }),
          title: "Začiatok trasy"
        }).addTo(MapSettings.Map);

        var uniqueId = Date.now() + "_" + Math.floor(Math.random() * 10000);
        var layerId = "poly_" + uniqueId;

        polyline._gpxinfo = {
          name: name,
          desc: desc,
          distance: Math.round(dist),
          ascending: ascend,
          descending: descend,
          filename: filename
        };

        polyline._startmarker = startMarker;

        // 💡 Pridáme aj referenciu na additional body
        polyline._additionalMarkers = window.moziGoMarkers.slice();

        window.moziGoRoutes[layerId] = polyline;
				var popupContent = "<b>" + name + "</b><br>";

				// pridaj len ak je farba trasy modrá
				if (color === "#0000FF") {
				popupContent += "<a href='delphiapp://showroute?file=\"" + filename +
                "\"&layerid=" + layerId + "'>📌 Look for caches around this route 📌️</a><br>";
				}
				popupContent +=
				"<a href='#' onclick='removeMoziGoLayer(\"" + layerId + "\"); return false;'>❌ Delete</a><br>" +
				"<a href='#' onclick='deleteAllPolylines(); return false;'>🗑️ Delete all tracks</a><br>" +
				"<a href='#' onclick='clickOnInfoA(\"" + layerId + "\"); return false;'>ℹ️ Show info</a>"
				// pripoj popup k polyline
				polyline.bindPopup(popupContent);

        MapSettings.Map.fitBounds(polyline.getBounds());
      }
    }
  }

  parseGPX(gpxText, filename);
}


window.clickOnInfoA = function(id) {
  var poly = window.moziGoRoutes[id];
  if (!poly) return;
  var data = poly._gpxinfo || {};
  var count = Array.isArray(poly.getLatLngs()) ? poly.getLatLngs().length : 'n/a';
  var text =
    '<div id="dataid" style="font-size:14px; line-height:1.5">' +
    '&#9432; <b>Info about route/Info o trase</b><br><br>' +
    '&#128204; <b>Filename/Názov:</b> ' + (data.name || 'Unknown/Neznáma') + '<br>' +
    '&#128196; <b>File/Súbor:</b> ' + (data.filename || 'Unknown file/Neznámy súbor') + '<br>' +
    '&#128207; <b>Dĺžka:</b> ' + (data.distance || 'n/a') + ' m<br>' +
    '&#11014;&#11014; <b>Ascending/Stúpanie:</b> ' + (data.ascending || 'n/a') + ' m<br>' +
    '&#11015;&#11015; <b>Descending/Klesanie:</b> ' + (data.descending || 'n/a') + ' m<br>' +
    '&#128302; <b>Počet bodov:</b> ' + count + '<br>' +
    ((parseInt(data.ascending) > 0 && parseInt(data.descending) > 0) ?
      '<a class="lnk" href="/altitudeprofil" target="_blank" alt="' + data.filename + '">📈 Altitude profil/Výškový profil</a>'
      : '') +
    '</div>';
  var center = poly.getCenter ? poly.getCenter() : poly.getLatLngs()[0];
  L.popup().setLatLng(center).setContent(text).openOn(MapSettings.Map);
};
window.GMEinjectGPX = function(gpxText, filename) {
  try {
    drawAdvancedGPXPolylineFromText(gpxText, filename);
  } catch (e) {
    alert("GMEinjectGPX error: " + e.message);
  }
};

if (window.moziGoRoutes && window.moziGoRoutes[id]) {
  var poly = window.moziGoRoutes[id];
  if (MapSettings.Map.hasLayer(poly)) {
    MapSettings.Map.removeLayer(poly);
  }
  delete window.moziGoRoutes[id];
}
//# sourceURL=mojSkript.js




// ✅ Pridanie markeru na začiatok trasy pri vykreslení (platí pre D&D aj priame vloženie)
function addStartMarkerToPolyline(poly, startPoint) {
  console.log("🔰 Adding start marker", startPoint);
  var startMarker = L.marker(startPoint, {
    icon: L.icon({
      iconUrl: "https://maps.google.com/mapfiles/ms/icons/green-dot.png",
      iconSize: [20, 20],
      iconAnchor: [10, 20]
    }),
    title: "Začiatok trasy"
  }).addTo(MapSettings.Map);
  var startPoint = getLastPoint(route.points);
  addStartMarkerToPolyline(poly, startPoint);

  poly._startmarker = startMarker;
    var layerId = "poly_" + poly._leaflet_id;
    window.moziGoRoutes[layerId] = poly;
}

// ✅ Pridanie vlastnej ikonky pre wpt body
function createWptMarker(ll, name) {
  return L.marker(ll, {
    icon: L.icon({
      iconUrl: "https://maps.google.com/mapfiles/ms/icons/ltblue-dot.png",
      iconSize: [16, 16],
      iconAnchor: [8, 8],
      title: name,
      clickable: false
    })
  });
}

// ✅ Uloženie polyline do mapy aj so správnym ID
function registerPolyline(poly) {
  var layerId = "poly_" + poly._leaflet_id;
  if (!window.moziGoRoutes) window.moziGoRoutes = {};
  window.moziGoRoutes[layerId] = poly;
console.log("📌 Registered route:", layerId);
  return layerId;
}

// ✅ Zobrazí info popup pre danú trasu (začiatok trasy)
window.clickOnInfo = function(id) {
  var poly = window["poly_" + id];
  if (!poly) poly = window.moziGoRoutes["poly_" + id];
  if (!poly) return;

  var data = poly._gpxinfo || {};
  var latlngs = poly.getLatLngs();
  var flat = Array.isArray(latlngs[0]) ? latlngs.flat() : latlngs;
  var startPoint = flat[flat.length - 1];

  var count = flat.length;
  var text =
    '<div id="dataid" style="font-size:14px; line-height:1.5">' +
    '&#9432; <b>Info o trase</b><br><br>' +
    '&#128204; <b>Názov:</b> ' + (data.name || 'Neznáma') + '<br>' +
    '&#128196; <b>Súbor:</b> ' + (data.filename || 'Neznámy') + '<br>' +
    '&#128207; <b>Dĺžka:</b> ' + (data.distance || 'n/a') + ' m<br>' +
    '&#11014;&#11014; <b>Stúpanie:</b> ' + (data.ascending || 'n/a') + ' m<br>' +
    '&#11015;&#11015; <b>Klesanie:</b> ' + (data.descending || 'n/a') + ' m<br>' +
    '&#128302; <b>Počet bodov:</b> ' + count + '<br>' +
	((parseInt(data.ascending) > 0 && parseInt(data.descending) > 0) ?
      '<a class="lnk" href="/altitudeprofil" target="_blank" alt="' + data.filename + '">📈 Altitude profil/Výškový profil</a>'
      : '') +
	 '</div>';

  L.popup().setLatLng(startPoint).setContent(text).openOn(MapSettings.Map);
};

window.removeMoziGoLayer = function(id) {
  if (window.moziGoRoutes && window.moziGoRoutes[id]) {
    var poly = window.moziGoRoutes[id];

    // odstrániť trasu
    if (MapSettings.Map.hasLayer(poly)) {
      MapSettings.Map.removeLayer(poly);
      console.log("🧹 Removed polyline");
    }

    // odstrániť start marker
    if (poly._startmarker && MapSettings.Map.hasLayer(poly._startmarker)) {
      MapSettings.Map.removeLayer(poly._startmarker);
      console.log("❎ Removed start marker");
    }

    // odstrániť additional markers
    if (poly._additionalMarkers) {
      poly._additionalMarkers.forEach(function(m) {
        if (MapSettings.Map.hasLayer(m)) {
          MapSettings.Map.removeLayer(m);
        }
      });
      console.log("❎ Removed additional markers");
    }

    // odstrániť additional markers
    if (poly._additionalMarkers) {
      poly._additionalMarkers.forEach(function(m) {
        if (MapSettings.Map.hasLayer(m)) {
          MapSettings.Map.removeLayer(m);
        }
      });
      console.log("❎ Removed additional markers");
    }

    delete window.moziGoRoutes[id];
  }
};


// ✅ Hromadné mazanie
window.deleteAllPolylines = function() {
  if (!window.moziGoRoutes) {
    console.log("⚠️ moziGoRoutes is undefined");
    return;
  }
  console.log("🧹 Deleting all polylines");
  console.log("🗂️ IDs before delete:", Object.keys(window.moziGoRoutes));
  console.log("🧹 Deleting all polylines");
  for (var id in window.moziGoRoutes) {
    window.removeMoziGoLayer(id);
  }
// debugger;
  if (window.moziGoMarkers) {
  window.moziGoMarkers.forEach(function(marker) {
    if (MapSettings.Map.hasLayer(marker)) {
      MapSettings.Map.removeLayer(marker);
    }
  });
  window.moziGoMarkers = [];
}  
  window.moziGoRoutes = {};
};

function getLastPoint(points) {
  if (Array.isArray(points[0])) {
    const lastSegment = points[points.length - 1];
    return lastSegment[lastSegment.length - 1];
  } else {
    return points[points.length - 1];
  }
}

function openPopupImage(url) {
    var imageUrl = url;
    
    // Vytvorenie overlay v aktuálnom okne
    var overlay = document.createElement('div');
    overlay.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.9);z-index:9999;display:flex;flex-direction:column;justify-content:center;align-items:center;cursor:pointer;';
    
    var img = document.createElement('img');
    img.src = imageUrl;
    img.style.cssText = 'max-width:90%;max-height:80%;';
    
    // Jednoduchý informačný text s ikonou
    var infoText = document.createElement('div');
    infoText.innerHTML = '🖱️ Kliknite pre zatvorenie';
    infoText.style.cssText = 'color:white;font-size:16px;margin-top:20px;text-align:center;font-family:Arial,sans-serif;background:rgba(0,0,0,0.5);padding:8px 16px;border-radius:20px;';
    
    overlay.onclick = function() {
        document.body.removeChild(overlay);
    };
    
    overlay.appendChild(img);
    overlay.appendChild(infoText);
    document.body.appendChild(overlay);
}

