diff --git a/Makefile b/Makefile index 336e5120..65a244de 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,19 @@ -default: +default: mkdefault + +local: mklocal +mobile: mkmobile + +mkdefault: ./build.py +mklocal: + ./build.py local + +mkmobile: + ./build.py mobile + adb install -r build/mobile/IITC_Mobile-debug.apk + adb shell am start -n com.cradle.iitc_mobile/com.cradle.iitc_mobile.IITC_Mobile clean: ant -f mobile/build.xml clean + diff --git a/assets/prefer-iitc.psd b/assets/prefer-iitc.psd new file mode 100644 index 00000000..bf0e1424 Binary files /dev/null and b/assets/prefer-iitc.psd differ diff --git a/build.py b/build.py index 97f808e6..ec04387d 100755 --- a/build.py +++ b/build.py @@ -289,6 +289,7 @@ if buildMobile: if retcode != 0: print ("Error: mobile app failed to build. ant returned %d" % retcode) + exit(1) # ant may return 256, but python seems to allow only values <256 else: shutil.copy("mobile/bin/IITC_Mobile-%s.apk" % buildMobile, os.path.join(outDir,"IITC_Mobile-%s.apk" % buildMobile) ) diff --git a/code/artifact.js b/code/artifact.js index 88676ab5..d52abc72 100644 --- a/code/artifact.js +++ b/code/artifact.js @@ -20,7 +20,8 @@ window.artifact.setup = function() { addResumeFunction(artifact.idleResume); - artifact.requestData(); + // move the initial data request onto a very short timer. prevents thrown exceptions causing IITC boot failures + setTimeout (artifact.requestData, 1); artifact._layer = new L.LayerGroup(); addLayerGroup ('Artifacts (Jarvis shards)', artifact._layer, true); @@ -246,7 +247,10 @@ window.artifact.showArtifactList = function() { } if (data[type].fragments) { - row += 'Shard: #'+data[type].fragments.join(', #')+' '; + if (data[type].target) { + row += '
'; + } + row += 'Shard: #'+data[type].fragments.join(', #')+' '; sortVal = Math.min.apply(null, data[type].fragments); // use min shard number at portal as sort key } diff --git a/code/chat.js b/code/chat.js index 31d7092d..50cb8fec 100644 --- a/code/chat.js +++ b/code/chat.js @@ -106,7 +106,7 @@ window.chat.genPostData = function(isFaction, storageHash, getOlderMsgs) { // Currently this edge case is not handled. Let’s see if this is a // problem in crowded areas. $.extend(data, {minTimestampMs: min}); - // when requesting with an acutal minimum timestamp, request oldest rather than newest first. + // when requesting with an actual minimum timestamp, request oldest rather than newest first. // this matches the stock intel site, and ensures no gaps when continuing after an extended idle period if (min > -1) $.extend(data, {ascendingTimestampOrder: true}); } @@ -228,12 +228,12 @@ window.chat.renderCompact = function(oldMsgsWereAdded) { $.each(chat._public.data, function(guid, entry) { // skip player msgs if(!entry[1]) return true; - var pguid = entry[3]; + var nick = entry[3]; // ignore if player has newer data - if(data[pguid] && data[pguid][0] > entry[0]) return true; - data[pguid] = entry; + if(data[nick] && data[nick][0] > entry[0]) return true; + data[nick] = entry; }); - // data keys are now player guids instead of message guids. However, + // data keys are now player nicks instead of message guids. However, // it is all the same to renderData. chat.renderData(data, 'chatcompact', oldMsgsWereAdded); } @@ -350,7 +350,7 @@ window.chat.writeDataToHash = function(newData, storageHash, isPublicChannel, is // format: timestamp, autogenerated, HTML message - storageHash.data[json[0]] = [json[1], auto, chat.renderMsg(msg, nick, time, team, msgToPlayer, systemNarrowcast)]; + storageHash.data[json[0]] = [json[1], auto, chat.renderMsg(msg, nick, time, team, msgToPlayer, systemNarrowcast), nick]; }); } diff --git a/code/game_status.js b/code/game_status.js index 10fe8d2c..94d24a6f 100644 --- a/code/game_status.js +++ b/code/game_status.js @@ -6,7 +6,8 @@ window.updateGameScoreFailCount = 0; window.updateGameScore = function(data) { if(!data) { - window.postAjax('getGameScore', {}, window.updateGameScore); + // move the postAjax call onto a very short timer. this way, if it throws an exception, it won't prevent IITC booting + setTimeout (function() { window.postAjax('getGameScore', {}, window.updateGameScore); }, 1); return; } diff --git a/code/hooks.js b/code/hooks.js index fb295655..1de476f3 100644 --- a/code/hooks.js +++ b/code/hooks.js @@ -50,6 +50,10 @@ // iitcLoaded: called after IITC and all plugins loaded // portalDetailLoaded: called when a request to load full portal detail // completes. guid, success, details parameters +// paneChanged called when the current pane has changed. On desktop, +// this only selects the current chat pane; on mobile, it +// also switches between map, info and other panes defined +// by plugins window._hooks = {} window.VALID_HOOKS = [ @@ -60,30 +64,32 @@ window.VALID_HOOKS = [ 'publicChatDataAvailable', 'factionChatDataAvailable', 'requestFinished', 'nicknameClicked', 'geoSearch', 'iitcLoaded', - 'portalDetailLoaded']; + 'portalDetailLoaded', 'paneChanged']; window.runHooks = function(event, data) { if(VALID_HOOKS.indexOf(event) === -1) throw('Unknown event type: ' + event); if(!_hooks[event]) return true; - var interupted = false; + var interrupted = false; $.each(_hooks[event], function(ind, callback) { try { if (callback(data) === false) { - interupted = true; + interrupted = true; return false; //break from $.each } } catch(err) { console.error('error running hook '+event+', error: '+err); + debugger; } }); - return !interupted; + return !interrupted; } window.addHook = function(event, callback) { if(VALID_HOOKS.indexOf(event) === -1) { console.error('addHook: Unknown event type: ' + event + ' - ignoring'); + debugger; return; } diff --git a/code/map_data_calc_tools.js b/code/map_data_calc_tools.js index 884acc40..a2c3369c 100644 --- a/code/map_data_calc_tools.js +++ b/code/map_data_calc_tools.js @@ -6,7 +6,7 @@ // tile and a quadkey. Both the bounds and the quadkey are “somewhat” // required to get complete data. // -// Convertion functions courtesy of +// Conversion functions courtesy of // http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames diff --git a/code/map_data_render.js b/code/map_data_render.js index 6606a022..53ce23a4 100644 --- a/code/map_data_render.js +++ b/code/map_data_render.js @@ -470,7 +470,7 @@ window.Render.prototype.addPortalToMapLayer = function(portal) { this.portalClusters[cid].push(portal.options.guid); - // now, at this point, we could match the above re-clustr code - sorting, and adding/removing as necessary + // now, at this point, we could match the above re-cluster code - sorting, and adding/removing as necessary // however, it won't make a lot of visible difference compared to just pushing to the end of the list, then // adding to the visible layer if the list is below the limit if (this.portalClusters[cid].length < this.CLUSTER_PORTAL_LIMIT || portal.options.guid == selectedPortal || artifact.isInterestingPortal(portal.options.guid)) { diff --git a/code/map_data_request.js b/code/map_data_request.js index 9c4f52be..1326d852 100644 --- a/code/map_data_request.js +++ b/code/map_data_request.js @@ -16,8 +16,9 @@ window.MapDataRequest = function() { // no more than this many requests in parallel. stock site seems to rely on browser limits (6, usually), sending - // all requests at once. using our own queue limit ensures that other requests (e.g. chat) don't get postponed for too long - this.MAX_REQUESTS = 6; + // many requests at once. + // using our own queue limit ensures that other requests (e.g. chat, portal details) don't get delayed + this.MAX_REQUESTS = 5; // no more than this many tiles in one request // as of 2013-11-11, or possibly the release before that, the stock site was changed to only request four tiles at a time @@ -28,7 +29,7 @@ window.MapDataRequest = function() { this.MIN_TILES_PER_REQUEST = 4; // number of times to retry a tile after a 'bad' error (i.e. not a timeout) - this.MAX_TILE_RETRIES = 1; + this.MAX_TILE_RETRIES = 2; // refresh timers this.MOVE_REFRESH = 1; //time, after a map move (pan/zoom) before starting the refresh processing diff --git a/code/munge.js b/code/munge.js index f696cce0..30a5ecc1 100644 --- a/code/munge.js +++ b/code/munge.js @@ -12,50 +12,58 @@ ;(function(){ var requestParameterMunges = [ - // obsolete munge sets (they don't have some of the new parameters) deleted + // all old munge sets deleted - there's no sign that any old ones will become active again - // set 10 - 2013-11-27 - { - 'dashboard.getArtifactInfo': 'artifacts', // GET_ARTIFACT_INFO - 'dashboard.getGameScore': '4oid643d9zc168hs', // GET_GAME_SCORE - 'dashboard.getPaginatedPlexts': 's1msyywq51ntudpe', // GET_PAGINATED_PLEXTS - 'dashboard.getThinnedEntities': '4467ff9bgxxe4csa', // GET_THINNED_ENTITIES - 'dashboard.getPortalDetails': 'c00thnhf1yp3z6mn', // GET_PORTAL_DETAILS - 'dashboard.redeemReward': '66l9ivg39ygfqqjm', // REDEEM_REWARD - 'dashboard.sendInviteEmail': 'cgb7hi5hglv0xx8k', // SEND_INVITE_EMAIL - 'dashboard.sendPlext': 'etn9xq7brd6947kq', // SEND_PLEXT - - // common parameters - method: 'yyngyttbmmbuvdpa', - version: 'avz401t36lzrapis', - version_parameter: 'c5d0a5d608f729a1232bebdc12fb86ba5fb6c43f', - - // GET_THINNED_ENTITIES - quadKeys: '1mpmxz2yun22rwnn', - - // GET_PAGINATED_PLEXTS - desiredNumItems: 'nzd23jqm9k1cnnij', - minLatE6: '0dod6onpa1s4fezp', - minLngE6: 'soass3t7mm7anneo', - maxLatE6: 'cvarmr3o00ngylo1', - maxLngE6: 'udzwnlx07hzd3bfo', - minTimestampMs: '9iiiks138gkf8xho', - maxTimestampMs: '94wm0u3sc3sgzq7x', - chatTab: 'tqfj4a3okzn5v5o1', - ascendingTimestampOrder: '5jv1m90sq35u6utq', - - // SEND_PLEXT - message: '8exta9k7y8huhqmc', - latE6: 'kqek161gza3kjcry', - lngE6: '3dlxsqrjj2vcmhbc', -// chatTab: 'efaznrayv5n3jxs0', //guessed parameter name - only seen munged - - // GET_PORTAL_DETAILS - guid: 'seg6ohxgnqf9xu9w', - - // SEND_INVITE_EMAIL - inviteeEmailAddress: '8exta9k7y8huhqmc', - }, +// the current munge set auto-detection code is working very well. as any site update that breaks that detection +// code will also, almost certainly, change the munges in use, it seems pointless keeping this set up to date by hand +// at this time. If that auto-detection breaks, it may be easier to quicky add a munge set by hand than update +// the regular expressions, so the list-based code remains available for the future +// // set 11 - 2013-12-06 +// { +// 'dashboard.getArtifactInfo': 'artifacts', // GET_ARTIFACT_INFO +// 'dashboard.getGameScore': '4oid643d9zc168hs', // GET_GAME_SCORE +// 'dashboard.getPaginatedPlexts': 's1msyywq51ntudpe', // GET_PAGINATED_PLEXTS +// 'dashboard.getThinnedEntities': '4467ff9bgxxe4csa', // GET_THINNED_ENTITIES +// 'dashboard.getPortalDetails': 'c00thnhf1yp3z6mn', // GET_PORTAL_DETAILS +// 'dashboard.redeemReward': 'ivshfv9zvyfxyqcd', // REDEEM_REWARD +// 'dashboard.sendInviteEmail': '1rsx15vc0m8wwdax', // SEND_INVITE_EMAIL +// 'dashboard.sendPlext': 'tods2imd0xcfsug6', // SEND_PLEXT +// +// // common parameters +// method: '0wvzluo8av4sk17f', +// version: 'paeh4g353xu06kfg', +// version_parameter: '4acc1e3230c3fd66be3422c0df8dc637336bbd7c', +// +// // GET_THINNED_ENTITIES +// quadKeys: 'ilgv0w4dlldky1yh', +// +// // GET_PORTAL_DETAILS +// guid: '7o8tzmj6oxz1n5w3', +// +// // REDEEM_REWARD +// passcode: 'passcode', // no munging on this parameter +// +// // SEND_INVITE_EMAIL +// inviteeEmailAddress: 'p4rwszdfovuwfdgp', +// +// // GET_PAGINATED_PLEXTS +// desiredNumItems: 'kxsbuvc90l6f40xn', +// minLatE6: 'llizye3i5dbapxac', +// minLngE6: 'w01zpiba1mn5tsab', +// maxLatE6: 'd5phhqzj2tbsq599', +// maxLngE6: 'avq5srnvg431aehn', +// minTimestampMs: 'mhsav5by25wi4s46', +// maxTimestampMs: 'hpu7l8h7eccwytyt', +// chatTab: 'q9343nem7hs1v37b', +// ascendingTimestampOrder: '7pc5c9ggh03pig1b', +// +// // SEND_PLEXT +// message: '8exta9k7y8huhqmc', +// latE6: '7ffwyf3zd2yf8xam', +// lngE6: 'n7ewiach2v22iy20', +//// chatTab: 'q9343nem7hs1v37b', // duplicate from GET_PAGINATED_PLEXTS +// +// }, ]; diff --git a/code/panes.js b/code/panes.js index 4c3898d4..c5ea4eea 100644 --- a/code/panes.js +++ b/code/panes.js @@ -3,6 +3,8 @@ window.show = function(id) { window.hideall(); + runHooks("paneChanged", id); + switch(id) { case 'full': window.chat.show('full'); @@ -27,9 +29,6 @@ window.show = function(id) { case 'info': window.smartphone.sideButton.click(); break; - default: - window.smartphone.mapButton.click(); - break; } if (typeof android !== 'undefined' && android && android.switchToPane) { diff --git a/code/portal_data.js b/code/portal_data.js index cf5aa62b..0caca9e1 100644 --- a/code/portal_data.js +++ b/code/portal_data.js @@ -21,6 +21,11 @@ window.getPortalLinks = function(guid) { return links; } +window.getPortalLinksCount = function(guid) { + var links = getPortalLinks(guid); + return links.in.length+links.out.length; +} + // search through the fields for all that reference a portal window.getPortalFields = function(guid) { @@ -40,6 +45,11 @@ window.getPortalFields = function(guid) { return fields; } +window.getPortalFieldsCount = function(guid) { + var fields = getPortalFields(guid); + return fields.length; +} + // find the lat/lon for a portal, using any and all available data // (we have the list of portals, the cached portal details, plus links and fields as sources of portal locations) @@ -79,3 +89,48 @@ window.findPortalLatLng = function(guid) { // no luck finding portal lat/lng return undefined; } + + +// get the AP gains from a portal, based only on the brief summary data from portals, links and fields +// not entirely accurate - but available for all portals on the screen +window.getPortalApGain = function(guid) { + + var p = window.portals[guid]; + if (p) { + var data = p.options.data; + + var linkCount = getPortalLinksCount(guid); + var fieldCount = getPortalFieldsCount(guid); + + var result = portalApGainMaths(data.resCount, linkCount, fieldCount); + return result; + } + + return undefined; +} + +// given counts of resonators, links and fields, calculate the available AP +// doesn't take account AP for resonator upgrades or AP for adding mods +window.portalApGainMaths = function(resCount, linkCount, fieldCount) { + + var deployAp = (8-resCount)*DEPLOY_RESONATOR; + if (resCount == 0) deployAp += CAPTURE_PORTAL; + if (resCount != 8) deployAp += COMPLETION_BONUS; + // there could also be AP for upgrading existing resonators, and for deploying mods - but we don't have data for that + var friendlyAp = deployAp; + + var destroyResoAp = resCount*DESTROY_RESONATOR; + var destroyLinkAp = linkCount*DESTROY_LINK; + var destroyFieldAp = fieldCount*DESTROY_FIELD; + var captureAp = CAPTURE_PORTAL + 8 * DEPLOY_RESONATOR + COMPLETION_BONUS; + var destroyAp = destroyResoAp+destroyLinkAp+destroyFieldAp; + var enemyAp = destroyAp+captureAp; + + return { + friendlyAp: friendlyAp, + enemyAp: enemyAp, + destroyAp: destroyAp, + destroyResoAp: destroyResoAp, + captureAp: captureAp + } +} diff --git a/code/portal_detail.js b/code/portal_detail.js index e99d5b7a..0f5557ab 100644 --- a/code/portal_detail.js +++ b/code/portal_detail.js @@ -1,5 +1,5 @@ /// PORTAL DETAIL ////////////////////////////////////// -// code to retrieve the new potal detail data from the servers +// code to retrieve the new portal detail data from the servers // NOTE: the API for portal detailed information is NOT FINAL // this is a temporary measure to get things working again after a major change to the intel map @@ -54,6 +54,6 @@ window.portalDetail.request = function(guid) { -})(); // anonumous wrapper function end +})(); // anonymous wrapper function end diff --git a/code/portal_detail_display.js b/code/portal_detail_display.js index 231e9716..4fc9cd9b 100644 --- a/code/portal_detail_display.js +++ b/code/portal_detail_display.js @@ -5,7 +5,7 @@ window.renderPortalDetails = function(guid) { selectPortal(window.portals[guid] ? guid : null); - if (!portalDetail.isFresh(guid)) { + if (guid && !portalDetail.isFresh(guid)) { portalDetail.request(guid); } @@ -26,6 +26,11 @@ window.renderPortalDetails = function(guid) { var data = portal.options.data; var details = portalDetail.get(guid); + // details and data can get out of sync. if we have details, construct a matching 'data' + if (details) { + data = getPortalSummaryData(details); + } + var modDetails = details ? '
'+getModDetails(details)+'
' : ''; var miscDetails = details ? getPortalMiscDetails(guid,details) : ''; @@ -78,8 +83,8 @@ window.renderPortalDetails = function(guid) { } // portal level. start with basic data - then extend with fractional info in tooltip if available - var levelInt = data ? data.level : getPortalLevel(details); - var levelDetails = data.level; + var levelInt = portal.options.level; + var levelDetails = portal.options.level; if (details) { levelDetails = getPortalLevel(details); if(levelDetails != 8) { @@ -109,7 +114,7 @@ window.renderPortalDetails = function(guid) { } else { // non-android - a permalink for the portal - var permaHtml = $('
').html( $('').attr({href:permalinkUrl, target:'_blank', title:'Create a URL link to this portal'}).text('Portal link') ).html(); + var permaHtml = $('
').html( $('').attr({href:permalinkUrl, title:'Create a URL link to this portal'}).text('Portal link') ).html(); linkDetails.push ( '' ); // and a map link popup dialog @@ -178,7 +183,9 @@ window.getPortalMiscDetails = function(guid,d) { : null; var sinceText = time ? ['since', time] : null; - var linkedFields = ['fields', d.portalV2.linkedFields ? d.portalV2.linkedFields.length : 0]; + var fieldCount = getPortalFieldsCount(guid); + + var linkedFields = ['fields', fieldCount]; // collect and html-ify random data var randDetailsData = []; @@ -189,7 +196,7 @@ window.getPortalMiscDetails = function(guid,d) { randDetailsData.push ( getRangeText(d), getEnergyText(d), linksText, getAvgResoDistText(d), - linkedFields, getAttackApGainText(d), + linkedFields, getAttackApGainText(d,fieldCount), getHackDetailsText(d), getMitigationText(d) ); diff --git a/code/portal_detail_display_tools.js b/code/portal_detail_display_tools.js index a2891067..34cd3088 100644 --- a/code/portal_detail_display_tools.js +++ b/code/portal_detail_display_tools.js @@ -193,8 +193,13 @@ window.getResonatorDetails = function(d) { // slot: which slot this resonator occupies. Starts with 0 (east) and // rotates clockwise. So, last one is 7 (southeast). window.renderResonatorDetails = function(slot, level, nrg, dist, nick) { + if(OCTANTS[slot] === 'N') + var className = 'meter north'; + else + var className = 'meter'; + if(level === 0) { - var meter = ''; + var meter = ''; } else { var max = RESO_NRG[level]; var fillGrade = nrg/max*100; @@ -209,19 +214,19 @@ window.renderResonatorDetails = function(slot, level, nrg, dist, nick) { var color = (level < 3 ? "#9900FF" : "#FFFFFF"); - var lbar = ' ' + level + ' '; + var lbar = ' L ' + level + ' '; var fill = ''; - var meter = '' + fill + lbar + ''; + var meter = '' + fill + lbar + ''; } nick = nick ? ''+nick+'' : null; return [meter, nick || '']; } // calculate AP gain from destroying portal and then capturing it by deploying resonators -window.getAttackApGainText = function(d) { - var breakdown = getAttackApGain(d); +window.getAttackApGainText = function(d,fieldCount) { + var breakdown = getAttackApGain(d,fieldCount); var totalGain = breakdown.enemyAp; function tt(text) { diff --git a/code/portal_info.js b/code/portal_info.js index 56c47c23..69958823 100644 --- a/code/portal_info.js +++ b/code/portal_info.js @@ -68,22 +68,23 @@ window.getLinkAmpRangeBoost = function(d) { // (at the time of writing, only rare link amps have been seen in the wild, so there's a little guesswork at how // the stats work and combine - jon 2013-06-26) - // link amps scale: first is full, second half, the last two a quarter - var scale = [1.0, 0.5, 0.25, 0.25]; + // link amps scale: first is full, second a quarter, the last two an eigth + var scale = [1.0, 0.25, 0.125, 0.125]; - var boost = 1.0; // initial boost is 1.0 (i.e. no boost over standard range) + var boost = 0.0; // initial boost is 0.0 (i.e. no boost over standard range) var count = 0; - $.each(d.portalV2.linkedModArray, function(ind, mod) { - if(mod && mod.type === 'LINK_AMPLIFIER' && mod.stats && mod.stats.LINK_RANGE_MULTIPLIER) { - // link amp stat LINK_RANGE_MULTIPLIER is 2000 for rare, and gives 2x boost to the range - var baseMultiplier = mod.stats.LINK_RANGE_MULTIPLIER/1000; - boost += (baseMultiplier-1)*scale[count]; - count++; - } + var linkAmps = getPortalModsByType(d, 'LINK_AMPLIFIER'); + + $.each(linkAmps, function(ind, mod) { + // link amp stat LINK_RANGE_MULTIPLIER is 2000 for rare, and gives 2x boost to the range + // and very-rare is 7000 and gives 7x the range + var baseMultiplier = mod.stats.LINK_RANGE_MULTIPLIER/1000; + boost += baseMultiplier*scale[count]; + count++; }); - return boost; + return (count > 0) ? boost : 1.0; } @@ -99,11 +100,13 @@ window.getAvgResoDist = function(d) { return resos ? sum/resos : 0; } -window.getAttackApGain = function(d) { +window.getAttackApGain = function(d,fieldCount) { + if (!fieldCount) fieldCount = 0; + var resoCount = 0; var maxResonators = MAX_RESO_PER_PLAYER.slice(0); var curResonators = [ 0, 0, 0, 0, 0, 0, 0, 0, 0]; - + for(var n = PLAYER.level + 1; n < 9; n++) { maxResonators[n] = 0; } @@ -123,7 +126,7 @@ window.getAttackApGain = function(d) { }); var linkCount = d.portalV2.linkedEdges ? d.portalV2.linkedEdges.length : 0; - var fieldCount = d.portalV2.linkedFields ? d.portalV2.linkedFields.length : 0; + var resoAp = resoCount * DESTROY_RESONATOR; var linkAp = linkCount * DESTROY_LINK; @@ -307,4 +310,30 @@ window.getPortalHackDetails = function(d) { return {cooldown: cooldownTime, hacks: numHacks, burnout: cooldownTime*(numHacks-1)}; } +// given a detailed portal structure, return summary portal data, as seen in the map tile data +window.getPortalSummaryData = function(d) { + // NOTE: the summary data reports unclaimed portals as level 1 - not zero as elsewhere in IITC + var level = d.controllingTeam.team == "NEUTRAL" ? 1 : parseInt(getPortalLevel(d)); + var resCount = 0; + if (d.resonatorArray && d.resonatorArray.resonators) { + for (var x in d.resonatorArray.resonators) { + if (d.resonatorArray.resonators[x]) resCount++; + } + } + var maxEnergy = getTotalPortalEnergy(d); + var curEnergy = getCurrentPortalEnergy(d); + var health = maxEnergy>0 ? parseInt(curEnergy/maxEnergy*100) : 0; + + return { + level: level, + title: d.portalV2.descriptiveText.TITLE, + image: d.imageByUrl && d.imageByUrl.imageUrl, + resCount: resCount, + latE6: d.locationE6.latE6, + health: health, + team: d.controllingTeam.team, + lngE6: d.locationE6.lngE6, + type: 'portal' + }; +} diff --git a/code/smartphone.js b/code/smartphone.js index 56e0c57c..8078cbd4 100644 --- a/code/smartphone.js +++ b/code/smartphone.js @@ -66,40 +66,53 @@ window.runOnSmartphonesBeforeBoot = function() { } window.smartphoneInfo = function(data) { - var d = data.portalDetails; - var lvl = Math.floor(getPortalLevel(d)); - if(lvl == 0) - var t = 'L' + lvl + ''; + var guid = data.selectedPortalGuid; + if(!window.portals[guid]) return; + + var data = window.portals[selectedPortal].options.data; + var details = window.portalDetail.get(guid); + + var lvl = data.level; + if(data.team === "NEUTRAL") + var t = 'L0'; else var t = 'L' + lvl + ''; - var percentage = '0%'; - var totalEnergy = getTotalPortalEnergy(d); - if(getTotalPortalEnergy(d) > 0) { - percentage = Math.floor((getCurrentPortalEnergy(d) / getTotalPortalEnergy(d) * 100)) + '%'; + + var percentage = data.health; + if(details) { + var totalEnergy = getTotalPortalEnergy(details); + if(getTotalPortalEnergy(details) > 0) { + percentage = Math.floor(getCurrentPortalEnergy(details) / totalEnergy * 100); + } } - t += ' ' + percentage + ' '; - t += d.portalV2.descriptiveText.TITLE; + t += ' ' + percentage + '% '; + t += data.title; - var l,v,max,perc; - for(var i=0;i<8;i++) - { - var reso = d.resonatorArray.resonators[i]; - if(reso) { - l = parseInt(reso.level); - v = parseInt(reso.energyTotal); - max = RESO_NRG[l]; - perc = v/max*100; - } - else { - l = 0; - v = 0; - max = 0; - perc = 0; - } + if(details) { + var l,v,max,perc; + for(var i=0;i<8;i++) + { + var className = TEAM_TO_CSS[getTeam(details)]; + if(OCTANTS[i] === 'N') + className += ' north' + var reso = details.resonatorArray.resonators[i]; + if(reso) { + l = parseInt(reso.level); + v = parseInt(reso.energyTotal); + max = RESO_NRG[l]; + perc = v/max*100; + } + else { + l = 0; + v = 0; + max = 0; + perc = 0; + } - t += '
'; - t += '
'; - t += '
' + t += '
'; + t += '
'; + t += '
' + } } $('#mobileinfo').html(t); @@ -113,7 +126,7 @@ window.runOnSmartphonesAfterBoot = function() { // add a div/hook for updating mobile info $('#updatestatus').prepend('
'); - window.addHook('portalDetailsUpdated', window.smartphoneInfo); + window.addHook('portalSelected', window.smartphoneInfo); // init msg of status bar. hint for the user that a tap leads to the info screen $('#mobileinfo').html('
tap here for info screen
'); @@ -157,3 +170,9 @@ window.runOnSmartphonesAfterBoot = function() { window.MAX_DRAWN_LINKS = 200; window.MAX_DRAWN_FIELDS = 100; } + +window.useAndroidPanes = function() { + // isSmartphone is important to disable panes in desktop mode + return (typeof android !== 'undefined' && android && android.addPane && window.isSmartphone()); +} + diff --git a/code/utils_misc.js b/code/utils_misc.js index 75d213e8..09f8b7cc 100644 --- a/code/utils_misc.js +++ b/code/utils_misc.js @@ -122,7 +122,9 @@ window.convertCookieToLocalStorage = function(name) { // add thousand separators to given number. // http://stackoverflow.com/a/1990590/1684530 by Doug Neiner. window.digits = function(d) { - return (d+"").replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1 "); + // U+2009 - Thin Space. Recommended for use as a thousands separator... + // https://en.wikipedia.org/wiki/Space_(punctuation)#Table_of_spaces + return (d+"").replace(/(\d)(?=(\d\d\d)+(?!\d))/g, "$1 "); } @@ -267,11 +269,11 @@ window.androidCopy = function(text) { } window.androidPermalink = function() { - if(typeof android === 'undefined' || !android || !android.copy) + if(typeof android === 'undefined' || !android || !android.intentPosLink) return true; // i.e. execute other actions var center = map.getCenter(); - android.intentPosLink(center.lat, center.lng, map.getZoom(), "Intel Map", false); + android.intentPosLink(center.lat, center.lng, map.getZoom(), "Selected map view", false); return false; } diff --git a/external/L.Geodesic.js b/external/L.Geodesic.js index 8a6ef59e..5c54468e 100644 --- a/external/L.Geodesic.js +++ b/external/L.Geodesic.js @@ -34,48 +34,54 @@ Modified by qnstie 2013-07-17 to maintain compatibility with Leaflet.draw } }); } - - function geodesicConvertLine(startLatlng, endLatlng, convertedPoints) { - var i, - R = 6378137, // earth radius in meters (doesn't have to be exact) - maxlength = 5000, // meters before splitting - d2r = L.LatLng.DEG_TO_RAD, - r2d = L.LatLng.RAD_TO_DEG, - lat1, lat2, lng1, lng2, dLng, d, segments, - f, A, B, x, y, z, fLat, fLng; - - dLng = (endLatlng.lng - startLatlng.lng) * d2r; - lat1 = startLatlng.lat * d2r; - lat2 = endLatlng.lat * d2r; - lng1 = startLatlng.lng * d2r; - lng2 = endLatlng.lng * d2r; - // http://en.wikipedia.org/wiki/Great-circle_distance - d = Math.atan2(Math.sqrt( Math.pow(Math.cos(lat2) * Math.sin(dLng), 2) + Math.pow(Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLng), 2) ), Math.sin(lat1) * Math.sin(lat2) + Math.cos(lat1) * Math.cos(lat2) * Math.cos(dLng)); + // alternative geodesic line intermediate points function + // as north/south lines have very little curvature in the projection, we cam use longitude (east/west) seperation + // to calculate intermediate points. hopeefully this will avoid the rounding issues seen in the full intermediate + // points code that have been seen + function geodesicConvertLine(startLatLng, endLatLng, convertedPoints) { + var R = 6378137; // earth radius in meters (doesn't have to be exact) + var d2r = L.LatLng.DEG_TO_RAD; + var r2d = L.LatLng.RAD_TO_DEG; - segments = Math.ceil(d * R / maxlength); - // loop starts at 1 - we don't add the very first point - // loop ends before 'segments' is reached - we don't add the very last point here but outside the loop - // (this was to fix a bug - https://github.com/jonatkins/ingress-intel-total-conversion/issues/471 - // rounding errors? maths bug? not sure - but it solves the issue! and is a slight optimisation) - for (i = 1; i < segments; i++) { - // http://williams.best.vwh.net/avform.htm#Intermediate - // modified to handle longitude above +-180 degrees - f = i / segments; - A = Math.sin((1-f)*d) / Math.sin(d); - B = Math.sin(f*d) / Math.sin(d); - x = A * Math.cos(lat1) * Math.cos(0) + B * Math.cos(lat2) * Math.cos(dLng); - y = A * Math.cos(lat1) * Math.sin(0) + B * Math.cos(lat2) * Math.sin(dLng); - z = A * Math.sin(lat1) + B * Math.sin(lat2); - fLat = r2d * Math.atan2(z, Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2))); - fLng = r2d * (Math.atan2(y, x)+lng1); + // maths based on http://williams.best.vwh.net/avform.htm#Int - convertedPoints.push(L.latLng([fLat, fLng])); + var lat1 = startLatLng.lat * d2r; + var lat2 = endLatLng.lat * d2r; + var lng1 = startLatLng.lng * d2r; + var lng2 = endLatLng.lng * d2r; + + var dLng = lng2-lng1; + + var segments = Math.floor(Math.abs(dLng * R / 5000)); + + if (segments > 1) { + // pre-calculate some constant values for the loop + var sinLat1 = Math.sin(lat1); + var sinLat2 = Math.sin(lat2); + var cosLat1 = Math.cos(lat1); + var cosLat2 = Math.cos(lat2); + + var sinLat1CosLat2 = sinLat1*cosLat2; + var sinLat2CosLat1 = sinLat2*cosLat1; + + var cosLat1CosLat2SinDLng = cosLat1*cosLat2*Math.sin(dLng); + + for (var i=1; i < segments; i++) { + var iLng = lng1+dLng*(i/segments); + var iLat = Math.atan( (sinLat1CosLat2*Math.sin(lng2-iLng) + sinLat2CosLat1*Math.sin(iLng-lng1)) + / cosLat1CosLat2SinDLng) + + var point = L.latLng ( [iLat*r2d, iLng*r2d] ); + convertedPoints.push(point); + } } - // push the final point unmodified - convertedPoints.push(L.latLng(endLatlng)); + + convertedPoints.push(L.latLng(endLatLng)); } + + L.geodesicConvertLines = function (latlngs, fill) { if (latlngs.length == 0) { return []; diff --git a/external/leaflet-src.js b/external/leaflet-src.js index fa26f6e2..0047c611 100644 --- a/external/leaflet-src.js +++ b/external/leaflet-src.js @@ -7,7 +7,7 @@ var oldL = window.L, L = {}; -L.version = '0.7'; +L.version = '0.7.1'; // define Leaflet for Node module pattern loaders, including Browserify if (typeof module === 'object' && typeof module.exports === 'object') { @@ -134,21 +134,16 @@ L.Util = { } return ((!existingUrl || existingUrl.indexOf('?') === -1) ? '?' : '&') + params.join('&'); }, - - compileTemplate: function (str, data) { - // based on https://gist.github.com/padolsey/6008842 - str = str.replace(/"/g, '\\\"'); - str = str.replace(/\{ *([\w_]+) *\}/g, function (str, key) { - return '" + o["' + key + '"]' + (typeof data[key] === 'function' ? '(o)' : '') + ' + "'; - }); - // jshint evil: true - return new Function('o', 'return "' + str + '";'); - }, - template: function (str, data) { - var cache = L.Util._templateCache = L.Util._templateCache || {}; - cache[str] = cache[str] || L.Util.compileTemplate(str, data); - return cache[str](data); + return str.replace(/\{ *([\w_]+) *\}/g, function (str, key) { + var value = data[key]; + if (value === undefined) { + throw new Error('No value provided for variable ' + str); + } else if (typeof value === 'function') { + value = value(data); + } + return value; + }); }, isArray: Array.isArray || function (obj) { @@ -534,7 +529,7 @@ L.Mixin.Events.fire = L.Mixin.Events.fireEvent; doc = document.documentElement, ie3d = ie && ('transition' in doc.style), - webkit3d = ('WebKitCSSMatrix' in window) && ('m11' in new window.WebKitCSSMatrix()), + webkit3d = ('WebKitCSSMatrix' in window) && ('m11' in new window.WebKitCSSMatrix()) && !android23, gecko3d = 'MozPerspective' in doc.style, opera3d = 'OTransition' in doc.style, any3d = !window.L_DISABLE_3D && (ie3d || webkit3d || gecko3d || opera3d) && !phantomjs; @@ -1070,11 +1065,6 @@ L.DomUtil = { if (!disable3D && L.Browser.any3d) { el.style[L.DomUtil.TRANSFORM] = L.DomUtil.getTranslateString(point); - - // workaround for Android 2/3 stability (https://github.com/CloudMade/Leaflet/issues/69) - if (L.Browser.mobileWebkit3d) { - el.style.WebkitBackfaceVisibility = 'hidden'; - } } else { el.style.left = point.x + 'px'; el.style.top = point.y + 'px'; @@ -1770,6 +1760,8 @@ L.Map = L.Class.extend({ }, invalidateSize: function (options) { + if (!this._loaded) { return this; } + options = L.extend({ animate: false, pan: true @@ -1779,8 +1771,6 @@ L.Map = L.Class.extend({ this._sizeChanged = true; this._initialCenter = null; - if (!this._loaded) { return this; } - var newSize = this.getSize(), oldCenter = oldSize.divideBy(2).round(), newCenter = newSize.divideBy(2).round(), @@ -2857,11 +2847,9 @@ L.TileLayer = L.Class.extend({ /* Chrome 20 layouts much faster with top/left (verify with timeline, frames) Android 4 browser has display issues with top/left and requires transform instead - Android 2 browser requires top/left or tiles disappear on load or first drag - (reappear after zoom) https://github.com/CloudMade/Leaflet/issues/866 (other browsers don't currently care) - see debug/hacks/jitter.html for an example */ - L.DomUtil.setPosition(tile, tilePos, L.Browser.chrome || L.Browser.android23); + L.DomUtil.setPosition(tile, tilePos, L.Browser.chrome); this._tiles[tilePoint.x + ':' + tilePoint.y] = tile; @@ -4481,10 +4469,10 @@ L.FeatureGroup = L.LayerGroup.extend({ }, _propagateEvent: function (e) { - e = L.extend({}, e, { + e = L.extend({ layer: e.target, target: this - }); + }, e); this.fire(e.type, e); } }); @@ -5255,7 +5243,7 @@ L.Map.include((L.Path.SVG && !window.L_PREFER_CANVAS) || !L.Browser.canvas ? {} * and polylines (clipping, simplification, distances, etc.) */ -/*jshint bitwise:false */ // allow bitwise oprations for this file +/*jshint bitwise:false */ // allow bitwise operations for this file L.LineUtil = { @@ -5988,6 +5976,7 @@ L.CircleMarker = L.Circle.extend({ if (this._popup && this._popup._isOpen) { this._popup.setLatLng(latlng); } + return this; }, setRadius: function (radius) { @@ -6769,7 +6758,7 @@ L.Draggable = L.Class.extend({ L.DomUtil.enableImageDrag(); L.DomUtil.enableTextSelection(); - if (this._moved) { + if (this._moved && this._moving) { // ensure drag is not fired after dragend L.Util.cancelAnimFrame(this._animRequest); @@ -8903,8 +8892,8 @@ if (L.DomUtil.TRANSITION) { L.Map.include(!L.DomUtil.TRANSITION ? {} : { - _catchTransitionEnd: function () { - if (this._animatingZoom) { + _catchTransitionEnd: function (e) { + if (this._animatingZoom && e.propertyName.indexOf('transform') >= 0) { this._onZoomTransitionEnd(); } }, diff --git a/external/leaflet.js b/external/leaflet.js index 57324ea8..3023bbb7 100644 --- a/external/leaflet.js +++ b/external/leaflet.js @@ -3,7 +3,7 @@ (c) 2010-2013, Vladimir Agafonkin (c) 2010-2011, CloudMade */ -!function(t,e,i){var n=t.L,o={};o.version="0.7","object"==typeof module&&"object"==typeof module.exports?module.exports=o:"function"==typeof define&&define.amd&&define(o),o.noConflict=function(){return t.L=n,this},t.L=o,o.Util={extend:function(t){var e,i,n,o,s=Array.prototype.slice.call(arguments,1);for(i=0,n=s.length;n>i;i++){o=s[i]||{};for(e in o)o.hasOwnProperty(e)&&(t[e]=o[e])}return t},bind:function(t,e){var i=arguments.length>2?Array.prototype.slice.call(arguments,2):null;return function(){return t.apply(e,i||arguments)}},stamp:function(){var t=0,e="_leaflet_id";return function(i){return i[e]=i[e]||++t,i[e]}}(),invokeEach:function(t,e,i){var n,o;if("object"==typeof t){o=Array.prototype.slice.call(arguments,3);for(n in t)e.apply(i,[n,t[n]].concat(o));return!0}return!1},limitExecByInterval:function(t,e,i){var n,o;return function s(){var a=arguments;return n?(o=!0,void 0):(n=!0,setTimeout(function(){n=!1,o&&(s.apply(i,a),o=!1)},e),t.apply(i,a),void 0)}},falseFn:function(){return!1},formatNum:function(t,e){var i=Math.pow(10,e||5);return Math.round(t*i)/i},trim:function(t){return t.trim?t.trim():t.replace(/^\s+|\s+$/g,"")},splitWords:function(t){return o.Util.trim(t).split(/\s+/)},setOptions:function(t,e){return t.options=o.extend({},t.options,e),t.options},getParamString:function(t,e,i){var n=[];for(var o in t)n.push(encodeURIComponent(i?o.toUpperCase():o)+"="+encodeURIComponent(t[o]));return(e&&-1!==e.indexOf("?")?"&":"?")+n.join("&")},compileTemplate:function(t,e){return t=t.replace(/"/g,'\\"'),t=t.replace(/\{ *([\w_]+) *\}/g,function(t,i){return'" + o["'+i+'"]'+("function"==typeof e[i]?"(o)":"")+' + "'}),new Function("o",'return "'+t+'";')},template:function(t,e){var i=o.Util._templateCache=o.Util._templateCache||{};return i[t]=i[t]||o.Util.compileTemplate(t,e),i[t](e)},isArray:Array.isArray||function(t){return"[object Array]"===Object.prototype.toString.call(t)},emptyImageUrl:"data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs="},function(){function e(e){var i,n,o=["webkit","moz","o","ms"];for(i=0;it;t++)n._initHooks[t].call(this)}},e},o.Class.include=function(t){o.extend(this.prototype,t)},o.Class.mergeOptions=function(t){o.extend(this.prototype.options,t)},o.Class.addInitHook=function(t){var e=Array.prototype.slice.call(arguments,1),i="function"==typeof t?t:function(){this[t].apply(this,e)};this.prototype._initHooks=this.prototype._initHooks||[],this.prototype._initHooks.push(i)};var s="_leaflet_events";o.Mixin={},o.Mixin.Events={addEventListener:function(t,e,i){if(o.Util.invokeEach(t,this.addEventListener,this,e,i))return this;var n,a,r,h,l,u,c,d=this[s]=this[s]||{},p=i&&i!==this&&o.stamp(i);for(t=o.Util.splitWords(t),n=0,a=t.length;a>n;n++)r={action:e,context:i||this},h=t[n],p?(l=h+"_idx",u=l+"_len",c=d[l]=d[l]||{},c[p]||(c[p]=[],d[u]=(d[u]||0)+1),c[p].push(r)):(d[h]=d[h]||[],d[h].push(r));return this},hasEventListeners:function(t){var e=this[s];return!!e&&(t in e&&e[t].length>0||t+"_idx"in e&&e[t+"_idx_len"]>0)},removeEventListener:function(t,e,i){if(!this[s])return this;if(!t)return this.clearAllEventListeners();if(o.Util.invokeEach(t,this.removeEventListener,this,e,i))return this;var n,a,r,h,l,u,c,d,p,_=this[s],m=i&&i!==this&&o.stamp(i);for(t=o.Util.splitWords(t),n=0,a=t.length;a>n;n++)if(r=t[n],u=r+"_idx",c=u+"_len",d=_[u],e){if(h=m&&d?d[m]:_[r]){for(l=h.length-1;l>=0;l--)h[l].action!==e||i&&h[l].context!==i||(p=h.splice(l,1),p[0].action=o.Util.falseFn);i&&d&&0===h.length&&(delete d[m],_[c]--)}}else delete _[r],delete _[u],delete _[c];return this},clearAllEventListeners:function(){return delete this[s],this},fireEvent:function(t,e){if(!this.hasEventListeners(t))return this;var i,n,a,r,h,l=o.Util.extend({},e,{type:t,target:this}),u=this[s];if(u[t])for(i=u[t].slice(),n=0,a=i.length;a>n;n++)i[n].action.call(i[n].context,l);r=u[t+"_idx"];for(h in r)if(i=r[h].slice())for(n=0,a=i.length;a>n;n++)i[n].action.call(i[n].context,l);return this},addOneTimeEventListener:function(t,e,i){if(o.Util.invokeEach(t,this.addOneTimeEventListener,this,e,i))return this;var n=o.bind(function(){this.removeEventListener(t,e,i).removeEventListener(t,n,i)},this);return this.addEventListener(t,e,i).addEventListener(t,n,i)}},o.Mixin.Events.on=o.Mixin.Events.addEventListener,o.Mixin.Events.off=o.Mixin.Events.removeEventListener,o.Mixin.Events.once=o.Mixin.Events.addOneTimeEventListener,o.Mixin.Events.fire=o.Mixin.Events.fireEvent,function(){var n="ActiveXObject"in t,s=n&&!e.addEventListener,a=navigator.userAgent.toLowerCase(),r=-1!==a.indexOf("webkit"),h=-1!==a.indexOf("chrome"),l=-1!==a.indexOf("phantom"),u=-1!==a.indexOf("android"),c=-1!==a.search("android [23]"),d=-1!==a.indexOf("gecko"),p=typeof orientation!=i+"",_=t.navigator&&t.navigator.msPointerEnabled&&t.navigator.msMaxTouchPoints&&!t.PointerEvent,m=t.PointerEvent&&t.navigator.pointerEnabled&&t.navigator.maxTouchPoints||_,f="devicePixelRatio"in t&&t.devicePixelRatio>1||"matchMedia"in t&&t.matchMedia("(min-resolution:144dpi)")&&t.matchMedia("(min-resolution:144dpi)").matches,g=e.documentElement,v=n&&"transition"in g.style,y="WebKitCSSMatrix"in t&&"m11"in new t.WebKitCSSMatrix,P="MozPerspective"in g.style,L="OTransition"in g.style,x=!t.L_DISABLE_3D&&(v||y||P||L)&&!l,w=!t.L_NO_TOUCH&&!l&&function(){var t="ontouchstart";if(m||t in g)return!0;var i=e.createElement("div"),n=!1;return i.setAttribute?(i.setAttribute(t,"return;"),"function"==typeof i[t]&&(n=!0),i.removeAttribute(t),i=null,n):!1}();o.Browser={ie:n,ielt9:s,webkit:r,gecko:d&&!r&&!t.opera&&!n,android:u,android23:c,chrome:h,ie3d:v,webkit3d:y,gecko3d:P,opera3d:L,any3d:x,mobile:p,mobileWebkit:p&&r,mobileWebkit3d:p&&y,mobileOpera:p&&t.opera,touch:w,msPointer:_,pointer:m,retina:f}}(),o.Point=function(t,e,i){this.x=i?Math.round(t):t,this.y=i?Math.round(e):e},o.Point.prototype={clone:function(){return new o.Point(this.x,this.y)},add:function(t){return this.clone()._add(o.point(t))},_add:function(t){return this.x+=t.x,this.y+=t.y,this},subtract:function(t){return this.clone()._subtract(o.point(t))},_subtract:function(t){return this.x-=t.x,this.y-=t.y,this},divideBy:function(t){return this.clone()._divideBy(t)},_divideBy:function(t){return this.x/=t,this.y/=t,this},multiplyBy:function(t){return this.clone()._multiplyBy(t)},_multiplyBy:function(t){return this.x*=t,this.y*=t,this},round:function(){return this.clone()._round()},_round:function(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this},floor:function(){return this.clone()._floor()},_floor:function(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this},distanceTo:function(t){t=o.point(t);var e=t.x-this.x,i=t.y-this.y;return Math.sqrt(e*e+i*i)},equals:function(t){return t=o.point(t),t.x===this.x&&t.y===this.y},contains:function(t){return t=o.point(t),Math.abs(t.x)<=Math.abs(this.x)&&Math.abs(t.y)<=Math.abs(this.y)},toString:function(){return"Point("+o.Util.formatNum(this.x)+", "+o.Util.formatNum(this.y)+")"}},o.point=function(t,e,n){return t instanceof o.Point?t:o.Util.isArray(t)?new o.Point(t[0],t[1]):t===i||null===t?t:new o.Point(t,e,n)},o.Bounds=function(t,e){if(t)for(var i=e?[t,e]:t,n=0,o=i.length;o>n;n++)this.extend(i[n])},o.Bounds.prototype={extend:function(t){return t=o.point(t),this.min||this.max?(this.min.x=Math.min(t.x,this.min.x),this.max.x=Math.max(t.x,this.max.x),this.min.y=Math.min(t.y,this.min.y),this.max.y=Math.max(t.y,this.max.y)):(this.min=t.clone(),this.max=t.clone()),this},getCenter:function(t){return new o.Point((this.min.x+this.max.x)/2,(this.min.y+this.max.y)/2,t)},getBottomLeft:function(){return new o.Point(this.min.x,this.max.y)},getTopRight:function(){return new o.Point(this.max.x,this.min.y)},getSize:function(){return this.max.subtract(this.min)},contains:function(t){var e,i;return t="number"==typeof t[0]||t instanceof o.Point?o.point(t):o.bounds(t),t instanceof o.Bounds?(e=t.min,i=t.max):e=i=t,e.x>=this.min.x&&i.x<=this.max.x&&e.y>=this.min.y&&i.y<=this.max.y},intersects:function(t){t=o.bounds(t);var e=this.min,i=this.max,n=t.min,s=t.max,a=s.x>=e.x&&n.x<=i.x,r=s.y>=e.y&&n.y<=i.y;return a&&r},isValid:function(){return!(!this.min||!this.max)}},o.bounds=function(t,e){return!t||t instanceof o.Bounds?t:new o.Bounds(t,e)},o.Transformation=function(t,e,i,n){this._a=t,this._b=e,this._c=i,this._d=n},o.Transformation.prototype={transform:function(t,e){return this._transform(t.clone(),e)},_transform:function(t,e){return e=e||1,t.x=e*(this._a*t.x+this._b),t.y=e*(this._c*t.y+this._d),t},untransform:function(t,e){return e=e||1,new o.Point((t.x/e-this._b)/this._a,(t.y/e-this._d)/this._c)}},o.DomUtil={get:function(t){return"string"==typeof t?e.getElementById(t):t},getStyle:function(t,i){var n=t.style[i];if(!n&&t.currentStyle&&(n=t.currentStyle[i]),(!n||"auto"===n)&&e.defaultView){var o=e.defaultView.getComputedStyle(t,null);n=o?o[i]:null}return"auto"===n?null:n},getViewportOffset:function(t){var i,n=0,s=0,a=t,r=e.body,h=e.documentElement;do{if(n+=a.offsetTop||0,s+=a.offsetLeft||0,n+=parseInt(o.DomUtil.getStyle(a,"borderTopWidth"),10)||0,s+=parseInt(o.DomUtil.getStyle(a,"borderLeftWidth"),10)||0,i=o.DomUtil.getStyle(a,"position"),a.offsetParent===r&&"absolute"===i)break;if("fixed"===i){n+=r.scrollTop||h.scrollTop||0,s+=r.scrollLeft||h.scrollLeft||0;break}if("relative"===i&&!a.offsetLeft){var l=o.DomUtil.getStyle(a,"width"),u=o.DomUtil.getStyle(a,"max-width"),c=a.getBoundingClientRect();("none"!==l||"none"!==u)&&(s+=c.left+a.clientLeft),n+=c.top+(r.scrollTop||h.scrollTop||0);break}a=a.offsetParent}while(a);a=t;do{if(a===r)break;n-=a.scrollTop||0,s-=a.scrollLeft||0,a=a.parentNode}while(a);return new o.Point(s,n)},documentIsLtr:function(){return o.DomUtil._docIsLtrCached||(o.DomUtil._docIsLtrCached=!0,o.DomUtil._docIsLtr="ltr"===o.DomUtil.getStyle(e.body,"direction")),o.DomUtil._docIsLtr},create:function(t,i,n){var o=e.createElement(t);return o.className=i,n&&n.appendChild(o),o},hasClass:function(t,e){if(t.classList!==i)return t.classList.contains(e);var n=o.DomUtil._getClass(t);return n.length>0&&new RegExp("(^|\\s)"+e+"(\\s|$)").test(n)},addClass:function(t,e){if(t.classList!==i)for(var n=o.Util.splitWords(e),s=0,a=n.length;a>s;s++)t.classList.add(n[s]);else if(!o.DomUtil.hasClass(t,e)){var r=o.DomUtil._getClass(t);o.DomUtil._setClass(t,(r?r+" ":"")+e)}},removeClass:function(t,e){t.classList!==i?t.classList.remove(e):o.DomUtil._setClass(t,o.Util.trim((" "+o.DomUtil._getClass(t)+" ").replace(" "+e+" "," ")))},_setClass:function(t,e){t.className.baseVal===i?t.className=e:t.className.baseVal=e},_getClass:function(t){return t.className.baseVal===i?t.className:t.className.baseVal},setOpacity:function(t,e){if("opacity"in t.style)t.style.opacity=e;else if("filter"in t.style){var i=!1,n="DXImageTransform.Microsoft.Alpha";try{i=t.filters.item(n)}catch(o){if(1===e)return}e=Math.round(100*e),i?(i.Enabled=100!==e,i.Opacity=e):t.style.filter+=" progid:"+n+"(opacity="+e+")"}},testProp:function(t){for(var i=e.documentElement.style,n=0;ni||i===e?e:t),new o.LatLng(this.lat,i)}},o.latLng=function(t,e){return t instanceof o.LatLng?t:o.Util.isArray(t)?"number"==typeof t[0]||"string"==typeof t[0]?new o.LatLng(t[0],t[1],t[2]):null:t===i||null===t?t:"object"==typeof t&&"lat"in t?new o.LatLng(t.lat,"lng"in t?t.lng:t.lon):e===i?null:new o.LatLng(t,e)},o.LatLngBounds=function(t,e){if(t)for(var i=e?[t,e]:t,n=0,o=i.length;o>n;n++)this.extend(i[n])},o.LatLngBounds.prototype={extend:function(t){if(!t)return this;var e=o.latLng(t);return t=null!==e?e:o.latLngBounds(t),t instanceof o.LatLng?this._southWest||this._northEast?(this._southWest.lat=Math.min(t.lat,this._southWest.lat),this._southWest.lng=Math.min(t.lng,this._southWest.lng),this._northEast.lat=Math.max(t.lat,this._northEast.lat),this._northEast.lng=Math.max(t.lng,this._northEast.lng)):(this._southWest=new o.LatLng(t.lat,t.lng),this._northEast=new o.LatLng(t.lat,t.lng)):t instanceof o.LatLngBounds&&(this.extend(t._southWest),this.extend(t._northEast)),this},pad:function(t){var e=this._southWest,i=this._northEast,n=Math.abs(e.lat-i.lat)*t,s=Math.abs(e.lng-i.lng)*t;return new o.LatLngBounds(new o.LatLng(e.lat-n,e.lng-s),new o.LatLng(i.lat+n,i.lng+s))},getCenter:function(){return new o.LatLng((this._southWest.lat+this._northEast.lat)/2,(this._southWest.lng+this._northEast.lng)/2)},getSouthWest:function(){return this._southWest},getNorthEast:function(){return this._northEast},getNorthWest:function(){return new o.LatLng(this.getNorth(),this.getWest())},getSouthEast:function(){return new o.LatLng(this.getSouth(),this.getEast())},getWest:function(){return this._southWest.lng},getSouth:function(){return this._southWest.lat},getEast:function(){return this._northEast.lng},getNorth:function(){return this._northEast.lat},contains:function(t){t="number"==typeof t[0]||t instanceof o.LatLng?o.latLng(t):o.latLngBounds(t);var e,i,n=this._southWest,s=this._northEast;return t instanceof o.LatLngBounds?(e=t.getSouthWest(),i=t.getNorthEast()):e=i=t,e.lat>=n.lat&&i.lat<=s.lat&&e.lng>=n.lng&&i.lng<=s.lng},intersects:function(t){t=o.latLngBounds(t);var e=this._southWest,i=this._northEast,n=t.getSouthWest(),s=t.getNorthEast(),a=s.lat>=e.lat&&n.lat<=i.lat,r=s.lng>=e.lng&&n.lng<=i.lng;return a&&r},toBBoxString:function(){return[this.getWest(),this.getSouth(),this.getEast(),this.getNorth()].join(",")},equals:function(t){return t?(t=o.latLngBounds(t),this._southWest.equals(t.getSouthWest())&&this._northEast.equals(t.getNorthEast())):!1},isValid:function(){return!(!this._southWest||!this._northEast)}},o.latLngBounds=function(t,e){return!t||t instanceof o.LatLngBounds?t:new o.LatLngBounds(t,e)},o.Projection={},o.Projection.SphericalMercator={MAX_LATITUDE:85.0511287798,project:function(t){var e=o.LatLng.DEG_TO_RAD,i=this.MAX_LATITUDE,n=Math.max(Math.min(i,t.lat),-i),s=t.lng*e,a=n*e;return a=Math.log(Math.tan(Math.PI/4+a/2)),new o.Point(s,a)},unproject:function(t){var e=o.LatLng.RAD_TO_DEG,i=t.x*e,n=(2*Math.atan(Math.exp(t.y))-Math.PI/2)*e;return new o.LatLng(n,i)}},o.Projection.LonLat={project:function(t){return new o.Point(t.lng,t.lat)},unproject:function(t){return new o.LatLng(t.y,t.x)}},o.CRS={latLngToPoint:function(t,e){var i=this.projection.project(t),n=this.scale(e);return this.transformation._transform(i,n)},pointToLatLng:function(t,e){var i=this.scale(e),n=this.transformation.untransform(t,i);return this.projection.unproject(n)},project:function(t){return this.projection.project(t)},scale:function(t){return 256*Math.pow(2,t)},getSize:function(t){var e=this.scale(t);return o.point(e,e)}},o.CRS.Simple=o.extend({},o.CRS,{projection:o.Projection.LonLat,transformation:new o.Transformation(1,0,-1,0),scale:function(t){return Math.pow(2,t)}}),o.CRS.EPSG3857=o.extend({},o.CRS,{code:"EPSG:3857",projection:o.Projection.SphericalMercator,transformation:new o.Transformation(.5/Math.PI,.5,-.5/Math.PI,.5),project:function(t){var e=this.projection.project(t),i=6378137;return e.multiplyBy(i)}}),o.CRS.EPSG900913=o.extend({},o.CRS.EPSG3857,{code:"EPSG:900913"}),o.CRS.EPSG4326=o.extend({},o.CRS,{code:"EPSG:4326",projection:o.Projection.LonLat,transformation:new o.Transformation(1/360,.5,-1/360,.5)}),o.Map=o.Class.extend({includes:o.Mixin.Events,options:{crs:o.CRS.EPSG3857,fadeAnimation:o.DomUtil.TRANSITION&&!o.Browser.android23,trackResize:!0,markerZoomAnimation:o.DomUtil.TRANSITION&&o.Browser.any3d},initialize:function(t,e){e=o.setOptions(this,e),this._initContainer(t),this._initLayout(),this._onResize=o.bind(this._onResize,this),this._initEvents(),e.maxBounds&&this.setMaxBounds(e.maxBounds),e.center&&e.zoom!==i&&this.setView(o.latLng(e.center),e.zoom,{reset:!0}),this._handlers=[],this._layers={},this._zoomBoundLayers={},this._tileLayersNum=0,this.callInitHooks(),this._addLayers(e.layers)},setView:function(t,e){return e=e===i?this.getZoom():e,this._resetView(o.latLng(t),this._limitZoom(e)),this},setZoom:function(t,e){return this._loaded?this.setView(this.getCenter(),t,{zoom:e}):(this._zoom=this._limitZoom(t),this)},zoomIn:function(t,e){return this.setZoom(this._zoom+(t||1),e)},zoomOut:function(t,e){return this.setZoom(this._zoom-(t||1),e)},setZoomAround:function(t,e,i){var n=this.getZoomScale(e),s=this.getSize().divideBy(2),a=t instanceof o.Point?t:this.latLngToContainerPoint(t),r=a.subtract(s).multiplyBy(1-1/n),h=this.containerPointToLatLng(s.add(r));return this.setView(h,e,{zoom:i})},fitBounds:function(t,e){e=e||{},t=t.getBounds?t.getBounds():o.latLngBounds(t);var i=o.point(e.paddingTopLeft||e.padding||[0,0]),n=o.point(e.paddingBottomRight||e.padding||[0,0]),s=this.getBoundsZoom(t,!1,i.add(n)),a=n.subtract(i).divideBy(2),r=this.project(t.getSouthWest(),s),h=this.project(t.getNorthEast(),s),l=this.unproject(r.add(h).divideBy(2).add(a),s);return s=e&&e.maxZoom?Math.min(e.maxZoom,s):s,this.setView(l,s,e)},fitWorld:function(t){return this.fitBounds([[-90,-180],[90,180]],t)},panTo:function(t,e){return this.setView(t,this._zoom,{pan:e})},panBy:function(t){return this.fire("movestart"),this._rawPanBy(o.point(t)),this.fire("move"),this.fire("moveend")},setMaxBounds:function(t){return t=o.latLngBounds(t),this.options.maxBounds=t,t?(this._loaded&&this._panInsideMaxBounds(),this.on("moveend",this._panInsideMaxBounds,this)):this.off("moveend",this._panInsideMaxBounds,this)},panInsideBounds:function(t,e){var i=this.getCenter(),n=this._limitCenter(i,this._zoom,t);return i.equals(n)?this:this.panTo(n,e)},addLayer:function(t){var e=o.stamp(t);return this._layers[e]?this:(this._layers[e]=t,!t.options||isNaN(t.options.maxZoom)&&isNaN(t.options.minZoom)||(this._zoomBoundLayers[e]=t,this._updateZoomLevels()),this.options.zoomAnimation&&o.TileLayer&&t instanceof o.TileLayer&&(this._tileLayersNum++,this._tileLayersToLoad++,t.on("load",this._onTileLayerLoad,this)),this._loaded&&this._layerAdd(t),this)},removeLayer:function(t){var e=o.stamp(t);return this._layers[e]?(this._loaded&&t.onRemove(this),delete this._layers[e],this._loaded&&this.fire("layerremove",{layer:t}),this._zoomBoundLayers[e]&&(delete this._zoomBoundLayers[e],this._updateZoomLevels()),this.options.zoomAnimation&&o.TileLayer&&t instanceof o.TileLayer&&(this._tileLayersNum--,this._tileLayersToLoad--,t.off("load",this._onTileLayerLoad,this)),this):this},hasLayer:function(t){return t?o.stamp(t)in this._layers:!1},eachLayer:function(t,e){for(var i in this._layers)t.call(e,this._layers[i]);return this},invalidateSize:function(t){t=o.extend({animate:!1,pan:!0},t===!0?{animate:!0}:t);var e=this.getSize();if(this._sizeChanged=!0,this._initialCenter=null,!this._loaded)return this;var i=this.getSize(),n=e.divideBy(2).round(),s=i.divideBy(2).round(),a=n.subtract(s);return a.x||a.y?(t.animate&&t.pan?this.panBy(a):(t.pan&&this._rawPanBy(a),this.fire("move"),t.debounceMoveend?(clearTimeout(this._sizeTimer),this._sizeTimer=setTimeout(o.bind(this.fire,this,"moveend"),200)):this.fire("moveend")),this.fire("resize",{oldSize:e,newSize:i})):this},addHandler:function(t,e){if(!e)return this;var i=this[t]=new e(this);return this._handlers.push(i),this.options[t]&&i.enable(),this},remove:function(){this._loaded&&this.fire("unload"),this._initEvents("off");try{delete this._container._leaflet}catch(t){this._container._leaflet=i}return this._clearPanes(),this._clearControlPos&&this._clearControlPos(),this._clearHandlers(),this},getCenter:function(){return this._checkIfLoaded(),this._initialCenter&&!this._moved()?this._initialCenter:this.layerPointToLatLng(this._getCenterLayerPoint())},getZoom:function(){return this._zoom},getBounds:function(){var t=this.getPixelBounds(),e=this.unproject(t.getBottomLeft()),i=this.unproject(t.getTopRight());return new o.LatLngBounds(e,i)},getMinZoom:function(){return this.options.minZoom===i?this._layersMinZoom===i?0:this._layersMinZoom:this.options.minZoom},getMaxZoom:function(){return this.options.maxZoom===i?this._layersMaxZoom===i?1/0:this._layersMaxZoom:this.options.maxZoom},getBoundsZoom:function(t,e,i){t=o.latLngBounds(t);var n,s=this.getMinZoom()-(e?1:0),a=this.getMaxZoom(),r=this.getSize(),h=t.getNorthWest(),l=t.getSouthEast(),u=!0;i=o.point(i||[0,0]);do s++,n=this.project(l,s).subtract(this.project(h,s)).add(i),u=e?n.x=s);return u&&e?null:e?s:s-1},getSize:function(){return(!this._size||this._sizeChanged)&&(this._size=new o.Point(this._container.clientWidth,this._container.clientHeight),this._sizeChanged=!1),this._size.clone()},getPixelBounds:function(){var t=this._getTopLeftPoint();return new o.Bounds(t,t.add(this.getSize()))},getPixelOrigin:function(){return this._checkIfLoaded(),this._initialTopLeftPoint},getPanes:function(){return this._panes},getContainer:function(){return this._container},getZoomScale:function(t){var e=this.options.crs;return e.scale(t)/e.scale(this._zoom)},getScaleZoom:function(t){return this._zoom+Math.log(t)/Math.LN2},project:function(t,e){return e=e===i?this._zoom:e,this.options.crs.latLngToPoint(o.latLng(t),e)},unproject:function(t,e){return e=e===i?this._zoom:e,this.options.crs.pointToLatLng(o.point(t),e)},layerPointToLatLng:function(t){var e=o.point(t).add(this.getPixelOrigin());return this.unproject(e)},latLngToLayerPoint:function(t){var e=this.project(o.latLng(t))._round();return e._subtract(this.getPixelOrigin())},containerPointToLayerPoint:function(t){return o.point(t).subtract(this._getMapPanePos())},layerPointToContainerPoint:function(t){return o.point(t).add(this._getMapPanePos())},containerPointToLatLng:function(t){var e=this.containerPointToLayerPoint(o.point(t));return this.layerPointToLatLng(e)},latLngToContainerPoint:function(t){return this.layerPointToContainerPoint(this.latLngToLayerPoint(o.latLng(t)))},mouseEventToContainerPoint:function(t){return o.DomEvent.getMousePosition(t,this._container)},mouseEventToLayerPoint:function(t){return this.containerPointToLayerPoint(this.mouseEventToContainerPoint(t))},mouseEventToLatLng:function(t){return this.layerPointToLatLng(this.mouseEventToLayerPoint(t))},_initContainer:function(t){var e=this._container=o.DomUtil.get(t);if(!e)throw new Error("Map container not found.");if(e._leaflet)throw new Error("Map container is already initialized.");e._leaflet=!0},_initLayout:function(){var t=this._container;o.DomUtil.addClass(t,"leaflet-container"+(o.Browser.touch?" leaflet-touch":"")+(o.Browser.retina?" leaflet-retina":"")+(o.Browser.ielt9?" leaflet-oldie":"")+(this.options.fadeAnimation?" leaflet-fade-anim":""));var e=o.DomUtil.getStyle(t,"position");"absolute"!==e&&"relative"!==e&&"fixed"!==e&&(t.style.position="relative"),this._initPanes(),this._initControlPos&&this._initControlPos()},_initPanes:function(){var t=this._panes={};this._mapPane=t.mapPane=this._createPane("leaflet-map-pane",this._container),this._tilePane=t.tilePane=this._createPane("leaflet-tile-pane",this._mapPane),t.objectsPane=this._createPane("leaflet-objects-pane",this._mapPane),t.shadowPane=this._createPane("leaflet-shadow-pane"),t.overlayPane=this._createPane("leaflet-overlay-pane"),t.markerPane=this._createPane("leaflet-marker-pane"),t.popupPane=this._createPane("leaflet-popup-pane");var e=" leaflet-zoom-hide";this.options.markerZoomAnimation||(o.DomUtil.addClass(t.markerPane,e),o.DomUtil.addClass(t.shadowPane,e),o.DomUtil.addClass(t.popupPane,e))},_createPane:function(t,e){return o.DomUtil.create("div",t,e||this._panes.objectsPane)},_clearPanes:function(){this._container.removeChild(this._mapPane)},_addLayers:function(t){t=t?o.Util.isArray(t)?t:[t]:[];for(var e=0,i=t.length;i>e;e++)this.addLayer(t[e])},_resetView:function(t,e,i,n){var s=this._zoom!==e;n||(this.fire("movestart"),s&&this.fire("zoomstart")),this._zoom=e,this._initialCenter=t,this._initialTopLeftPoint=this._getNewTopLeftPoint(t),i?this._initialTopLeftPoint._add(this._getMapPanePos()):o.DomUtil.setPosition(this._mapPane,new o.Point(0,0)),this._tileLayersToLoad=this._tileLayersNum;var a=!this._loaded;this._loaded=!0,a&&(this.fire("load"),this.eachLayer(this._layerAdd,this)),this.fire("viewreset",{hard:!i}),this.fire("move"),(s||n)&&this.fire("zoomend"),this.fire("moveend",{hard:!i})},_rawPanBy:function(t){o.DomUtil.setPosition(this._mapPane,this._getMapPanePos().subtract(t))},_getZoomSpan:function(){return this.getMaxZoom()-this.getMinZoom()},_updateZoomLevels:function(){var t,e=1/0,n=-1/0,o=this._getZoomSpan();for(t in this._zoomBoundLayers){var s=this._zoomBoundLayers[t];isNaN(s.options.minZoom)||(e=Math.min(e,s.options.minZoom)),isNaN(s.options.maxZoom)||(n=Math.max(n,s.options.maxZoom))}t===i?this._layersMaxZoom=this._layersMinZoom=i:(this._layersMaxZoom=n,this._layersMinZoom=e),o!==this._getZoomSpan()&&this.fire("zoomlevelschange")},_panInsideMaxBounds:function(){this.panInsideBounds(this.options.maxBounds)},_checkIfLoaded:function(){if(!this._loaded)throw new Error("Set map center and zoom first.")},_initEvents:function(e){if(o.DomEvent){e=e||"on",o.DomEvent[e](this._container,"click",this._onMouseClick,this);var i,n,s=["dblclick","mousedown","mouseup","mouseenter","mouseleave","mousemove","contextmenu"];for(i=0,n=s.length;n>i;i++)o.DomEvent[e](this._container,s[i],this._fireMouseEvent,this);this.options.trackResize&&o.DomEvent[e](t,"resize",this._onResize,this)}},_onResize:function(){o.Util.cancelAnimFrame(this._resizeRequest),this._resizeRequest=o.Util.requestAnimFrame(function(){this.invalidateSize({debounceMoveend:!0})},this,!1,this._container)},_onMouseClick:function(t){!this._loaded||!t._simulated&&(this.dragging&&this.dragging.moved()||this.boxZoom&&this.boxZoom.moved())||o.DomEvent._skipped(t)||(this.fire("preclick"),this._fireMouseEvent(t))},_fireMouseEvent:function(t){if(this._loaded&&!o.DomEvent._skipped(t)){var e=t.type;if(e="mouseenter"===e?"mouseover":"mouseleave"===e?"mouseout":e,this.hasEventListeners(e)){"contextmenu"===e&&o.DomEvent.preventDefault(t);var i=this.mouseEventToContainerPoint(t),n=this.containerPointToLayerPoint(i),s=this.layerPointToLatLng(n);this.fire(e,{latlng:s,layerPoint:n,containerPoint:i,originalEvent:t})}}},_onTileLayerLoad:function(){this._tileLayersToLoad--,this._tileLayersNum&&!this._tileLayersToLoad&&this.fire("tilelayersload")},_clearHandlers:function(){for(var t=0,e=this._handlers.length;e>t;t++)this._handlers[t].disable()},whenReady:function(t,e){return this._loaded?t.call(e||this,this):this.on("load",t,e),this},_layerAdd:function(t){t.onAdd(this),this.fire("layeradd",{layer:t})},_getMapPanePos:function(){return o.DomUtil.getPosition(this._mapPane)},_moved:function(){var t=this._getMapPanePos();return t&&!t.equals([0,0])},_getTopLeftPoint:function(){return this.getPixelOrigin().subtract(this._getMapPanePos())},_getNewTopLeftPoint:function(t,e){var i=this.getSize()._divideBy(2);return this.project(t,e)._subtract(i)._round()},_latLngToNewLayerPoint:function(t,e,i){var n=this._getNewTopLeftPoint(i,e).add(this._getMapPanePos());return this.project(t,e)._subtract(n)},_getCenterLayerPoint:function(){return this.containerPointToLayerPoint(this.getSize()._divideBy(2))},_getCenterOffset:function(t){return this.latLngToLayerPoint(t).subtract(this._getCenterLayerPoint())},_limitCenter:function(t,e,i){if(!i)return t;var n=this.project(t,e),s=this.getSize().divideBy(2),a=new o.Bounds(n.subtract(s),n.add(s)),r=this._getBoundsOffset(a,i,e);return this.unproject(n.add(r),e)},_limitOffset:function(t,e){if(!e)return t;var i=this.getPixelBounds(),n=new o.Bounds(i.min.add(t),i.max.add(t));return t.add(this._getBoundsOffset(n,e))},_getBoundsOffset:function(t,e,i){var n=this.project(e.getNorthWest(),i).subtract(t.min),s=this.project(e.getSouthEast(),i).subtract(t.max),a=this._rebound(n.x,-s.x),r=this._rebound(n.y,-s.y);return new o.Point(a,r)},_rebound:function(t,e){return t+e>0?Math.round(t-e)/2:Math.max(0,Math.ceil(t))-Math.max(0,Math.floor(e))},_limitZoom:function(t){var e=this.getMinZoom(),i=this.getMaxZoom();return Math.max(e,Math.min(i,t))}}),o.map=function(t,e){return new o.Map(t,e)},o.Projection.Mercator={MAX_LATITUDE:85.0840591556,R_MINOR:6356752.314245179,R_MAJOR:6378137,project:function(t){var e=o.LatLng.DEG_TO_RAD,i=this.MAX_LATITUDE,n=Math.max(Math.min(i,t.lat),-i),s=this.R_MAJOR,a=this.R_MINOR,r=t.lng*e*s,h=n*e,l=a/s,u=Math.sqrt(1-l*l),c=u*Math.sin(h);c=Math.pow((1-c)/(1+c),.5*u);var d=Math.tan(.5*(.5*Math.PI-h))/c; -return h=-s*Math.log(d),new o.Point(r,h)},unproject:function(t){for(var e,i=o.LatLng.RAD_TO_DEG,n=this.R_MAJOR,s=this.R_MINOR,a=t.x*i/n,r=s/n,h=Math.sqrt(1-r*r),l=Math.exp(-t.y/n),u=Math.PI/2-2*Math.atan(l),c=15,d=1e-7,p=c,_=.1;Math.abs(_)>d&&--p>0;)e=h*Math.sin(u),_=Math.PI/2-2*Math.atan(l*Math.pow((1-e)/(1+e),.5*h))-u,u+=_;return new o.LatLng(u*i,a)}},o.CRS.EPSG3395=o.extend({},o.CRS,{code:"EPSG:3395",projection:o.Projection.Mercator,transformation:function(){var t=o.Projection.Mercator,e=t.R_MAJOR,i=.5/(Math.PI*e);return new o.Transformation(i,.5,-i,.5)}()}),o.TileLayer=o.Class.extend({includes:o.Mixin.Events,options:{minZoom:0,maxZoom:18,tileSize:256,subdomains:"abc",errorTileUrl:"",attribution:"",zoomOffset:0,opacity:1,unloadInvisibleTiles:o.Browser.mobile,updateWhenIdle:o.Browser.mobile},initialize:function(t,e){e=o.setOptions(this,e),e.detectRetina&&o.Browser.retina&&e.maxZoom>0&&(e.tileSize=Math.floor(e.tileSize/2),e.zoomOffset++,e.minZoom>0&&e.minZoom--,this.options.maxZoom--),e.bounds&&(e.bounds=o.latLngBounds(e.bounds)),this._url=t;var i=this.options.subdomains;"string"==typeof i&&(this.options.subdomains=i.split(""))},onAdd:function(t){this._map=t,this._animated=t._zoomAnimated,this._initContainer(),t.on({viewreset:this._reset,moveend:this._update},this),this._animated&&t.on({zoomanim:this._animateZoom,zoomend:this._endZoomAnim},this),this.options.updateWhenIdle||(this._limitedUpdate=o.Util.limitExecByInterval(this._update,150,this),t.on("move",this._limitedUpdate,this)),this._reset(),this._update()},addTo:function(t){return t.addLayer(this),this},onRemove:function(t){this._container.parentNode.removeChild(this._container),t.off({viewreset:this._reset,moveend:this._update},this),this._animated&&t.off({zoomanim:this._animateZoom,zoomend:this._endZoomAnim},this),this.options.updateWhenIdle||t.off("move",this._limitedUpdate,this),this._container=null,this._map=null},bringToFront:function(){var t=this._map._panes.tilePane;return this._container&&(t.appendChild(this._container),this._setAutoZIndex(t,Math.max)),this},bringToBack:function(){var t=this._map._panes.tilePane;return this._container&&(t.insertBefore(this._container,t.firstChild),this._setAutoZIndex(t,Math.min)),this},getAttribution:function(){return this.options.attribution},getContainer:function(){return this._container},setOpacity:function(t){return this.options.opacity=t,this._map&&this._updateOpacity(),this},setZIndex:function(t){return this.options.zIndex=t,this._updateZIndex(),this},setUrl:function(t,e){return this._url=t,e||this.redraw(),this},redraw:function(){return this._map&&(this._reset({hard:!0}),this._update()),this},_updateZIndex:function(){this._container&&this.options.zIndex!==i&&(this._container.style.zIndex=this.options.zIndex)},_setAutoZIndex:function(t,e){var i,n,o,s=t.children,a=-e(1/0,-1/0);for(n=0,o=s.length;o>n;n++)s[n]!==this._container&&(i=parseInt(s[n].style.zIndex,10),isNaN(i)||(a=e(a,i)));this.options.zIndex=this._container.style.zIndex=(isFinite(a)?a:0)+e(1,-1)},_updateOpacity:function(){var t,e=this._tiles;if(o.Browser.ielt9)for(t in e)o.DomUtil.setOpacity(e[t],this.options.opacity);else o.DomUtil.setOpacity(this._container,this.options.opacity)},_initContainer:function(){var t=this._map._panes.tilePane;if(!this._container){if(this._container=o.DomUtil.create("div","leaflet-layer"),this._updateZIndex(),this._animated){var e="leaflet-tile-container";this._bgBuffer=o.DomUtil.create("div",e,this._container),this._tileContainer=o.DomUtil.create("div",e,this._container)}else this._tileContainer=this._container;t.appendChild(this._container),this.options.opacity<1&&this._updateOpacity()}},_reset:function(t){for(var e in this._tiles)this.fire("tileunload",{tile:this._tiles[e]});this._tiles={},this._tilesToLoad=0,this.options.reuseTiles&&(this._unusedTiles=[]),this._tileContainer.innerHTML="",this._animated&&t&&t.hard&&this._clearBgBuffer(),this._initContainer()},_getTileSize:function(){var t=this._map,e=t.getZoom()+this.options.zoomOffset,i=this.options.maxNativeZoom,n=this.options.tileSize;return i&&e>i&&(n=Math.round(t.getZoomScale(e)/t.getZoomScale(i)*n)),n},_update:function(){if(this._map){var t=this._map,e=t.getPixelBounds(),i=t.getZoom(),n=this._getTileSize();if(!(i>this.options.maxZoom||in;n++)this._addTile(a[n],l);this._tileContainer.appendChild(l)}},_tileShouldBeLoaded:function(t){if(t.x+":"+t.y in this._tiles)return!1;var e=this.options;if(!e.continuousWorld){var i=this._getWrapTileNum();if(e.noWrap&&(t.x<0||t.x>=i.x)||t.y<0||t.y>=i.y)return!1}if(e.bounds){var n=e.tileSize,o=t.multiplyBy(n),s=o.add([n,n]),a=this._map.unproject(o),r=this._map.unproject(s);if(e.continuousWorld||e.noWrap||(a=a.wrap(),r=r.wrap()),!e.bounds.intersects([a,r]))return!1}return!0},_removeOtherTiles:function(t){var e,i,n,o;for(o in this._tiles)e=o.split(":"),i=parseInt(e[0],10),n=parseInt(e[1],10),(it.max.x||nt.max.y)&&this._removeTile(o)},_removeTile:function(t){var e=this._tiles[t];this.fire("tileunload",{tile:e,url:e.src}),this.options.reuseTiles?(o.DomUtil.removeClass(e,"leaflet-tile-loaded"),this._unusedTiles.push(e)):e.parentNode===this._tileContainer&&this._tileContainer.removeChild(e),o.Browser.android||(e.onload=null,e.src=o.Util.emptyImageUrl),delete this._tiles[t]},_addTile:function(t,e){var i=this._getTilePos(t),n=this._getTile();o.DomUtil.setPosition(n,i,o.Browser.chrome||o.Browser.android23),this._tiles[t.x+":"+t.y]=n,this._loadTile(n,t),n.parentNode!==this._tileContainer&&e.appendChild(n)},_getZoomForUrl:function(){var t=this.options,e=this._map.getZoom();return t.zoomReverse&&(e=t.maxZoom-e),e+=t.zoomOffset,t.maxNativeZoom?Math.min(e,t.maxNativeZoom):e},_getTilePos:function(t){var e=this._map.getPixelOrigin(),i=this._getTileSize();return t.multiplyBy(i).subtract(e)},getTileUrl:function(t){return o.Util.template(this._url,o.extend({s:this._getSubdomain(t),z:t.z,x:t.x,y:t.y},this.options))},_getWrapTileNum:function(){var t=this._map.options.crs,e=t.getSize(this._map.getZoom());return e.divideBy(this.options.tileSize)},_adjustTilePoint:function(t){var e=this._getWrapTileNum();this.options.continuousWorld||this.options.noWrap||(t.x=(t.x%e.x+e.x)%e.x),this.options.tms&&(t.y=e.y-t.y-1),t.z=this._getZoomForUrl()},_getSubdomain:function(t){var e=Math.abs(t.x+t.y)%this.options.subdomains.length;return this.options.subdomains[e]},_getTile:function(){if(this.options.reuseTiles&&this._unusedTiles.length>0){var t=this._unusedTiles.pop();return this._resetTile(t),t}return this._createTile()},_resetTile:function(){},_createTile:function(){var t=o.DomUtil.create("img","leaflet-tile");return t.style.width=t.style.height=this._getTileSize()+"px",t.galleryimg="no",t.onselectstart=t.onmousemove=o.Util.falseFn,o.Browser.ielt9&&this.options.opacity!==i&&o.DomUtil.setOpacity(t,this.options.opacity),o.Browser.mobileWebkit3d&&(t.style.WebkitBackfaceVisibility="hidden"),t},_loadTile:function(t,e){t._layer=this,t.onload=this._tileOnLoad,t.onerror=this._tileOnError,this._adjustTilePoint(e),t.src=this.getTileUrl(e),this.fire("tileloadstart",{tile:t,url:t.src})},_tileLoaded:function(){this._tilesToLoad--,this._animated&&o.DomUtil.addClass(this._tileContainer,"leaflet-zoom-animated"),this._tilesToLoad||(this.fire("load"),this._animated&&(clearTimeout(this._clearBgBufferTimer),this._clearBgBufferTimer=setTimeout(o.bind(this._clearBgBuffer,this),500)))},_tileOnLoad:function(){var t=this._layer;this.src!==o.Util.emptyImageUrl&&(o.DomUtil.addClass(this,"leaflet-tile-loaded"),t.fire("tileload",{tile:this,url:this.src})),t._tileLoaded()},_tileOnError:function(){var t=this._layer;t.fire("tileerror",{tile:this,url:this.src});var e=t.options.errorTileUrl;e&&(this.src=e),t._tileLoaded()}}),o.tileLayer=function(t,e){return new o.TileLayer(t,e)},o.TileLayer.WMS=o.TileLayer.extend({defaultWmsParams:{service:"WMS",request:"GetMap",version:"1.1.1",layers:"",styles:"",format:"image/jpeg",transparent:!1},initialize:function(t,e){this._url=t;var i=o.extend({},this.defaultWmsParams),n=e.tileSize||this.options.tileSize;i.width=i.height=e.detectRetina&&o.Browser.retina?2*n:n;for(var s in e)this.options.hasOwnProperty(s)||"crs"===s||(i[s]=e[s]);this.wmsParams=i,o.setOptions(this,e)},onAdd:function(t){this._crs=this.options.crs||t.options.crs,this._wmsVersion=parseFloat(this.wmsParams.version);var e=this._wmsVersion>=1.3?"crs":"srs";this.wmsParams[e]=this._crs.code,o.TileLayer.prototype.onAdd.call(this,t)},getTileUrl:function(t){var e=this._map,i=this.options.tileSize,n=t.multiplyBy(i),s=n.add([i,i]),a=this._crs.project(e.unproject(n,t.z)),r=this._crs.project(e.unproject(s,t.z)),h=this._wmsVersion>=1.3&&this._crs===o.CRS.EPSG4326?[r.y,a.x,a.y,r.x].join(","):[a.x,r.y,r.x,a.y].join(","),l=o.Util.template(this._url,{s:this._getSubdomain(t)});return l+o.Util.getParamString(this.wmsParams,l,!0)+"&BBOX="+h},setParams:function(t,e){return o.extend(this.wmsParams,t),e||this.redraw(),this}}),o.tileLayer.wms=function(t,e){return new o.TileLayer.WMS(t,e)},o.TileLayer.Canvas=o.TileLayer.extend({options:{async:!1},initialize:function(t){o.setOptions(this,t)},redraw:function(){this._map&&(this._reset({hard:!0}),this._update());for(var t in this._tiles)this._redrawTile(this._tiles[t]);return this},_redrawTile:function(t){this.drawTile(t,t._tilePoint,this._map._zoom)},_createTile:function(){var t=o.DomUtil.create("canvas","leaflet-tile");return t.width=t.height=this.options.tileSize,t.onselectstart=t.onmousemove=o.Util.falseFn,t},_loadTile:function(t,e){t._layer=this,t._tilePoint=e,this._redrawTile(t),this.options.async||this.tileDrawn(t)},drawTile:function(){},tileDrawn:function(t){this._tileOnLoad.call(t)}}),o.tileLayer.canvas=function(t){return new o.TileLayer.Canvas(t)},o.ImageOverlay=o.Class.extend({includes:o.Mixin.Events,options:{opacity:1},initialize:function(t,e,i){this._url=t,this._bounds=o.latLngBounds(e),o.setOptions(this,i)},onAdd:function(t){this._map=t,this._image||this._initImage(),t._panes.overlayPane.appendChild(this._image),t.on("viewreset",this._reset,this),t.options.zoomAnimation&&o.Browser.any3d&&t.on("zoomanim",this._animateZoom,this),this._reset()},onRemove:function(t){t.getPanes().overlayPane.removeChild(this._image),t.off("viewreset",this._reset,this),t.options.zoomAnimation&&t.off("zoomanim",this._animateZoom,this)},addTo:function(t){return t.addLayer(this),this},setOpacity:function(t){return this.options.opacity=t,this._updateOpacity(),this},bringToFront:function(){return this._image&&this._map._panes.overlayPane.appendChild(this._image),this},bringToBack:function(){var t=this._map._panes.overlayPane;return this._image&&t.insertBefore(this._image,t.firstChild),this},setUrl:function(t){this._url=t,this._image.src=this._url},getAttribution:function(){return this.options.attribution},_initImage:function(){this._image=o.DomUtil.create("img","leaflet-image-layer"),this._map.options.zoomAnimation&&o.Browser.any3d?o.DomUtil.addClass(this._image,"leaflet-zoom-animated"):o.DomUtil.addClass(this._image,"leaflet-zoom-hide"),this._updateOpacity(),o.extend(this._image,{galleryimg:"no",onselectstart:o.Util.falseFn,onmousemove:o.Util.falseFn,onload:o.bind(this._onImageLoad,this),src:this._url})},_animateZoom:function(t){var e=this._map,i=this._image,n=e.getZoomScale(t.zoom),s=this._bounds.getNorthWest(),a=this._bounds.getSouthEast(),r=e._latLngToNewLayerPoint(s,t.zoom,t.center),h=e._latLngToNewLayerPoint(a,t.zoom,t.center)._subtract(r),l=r._add(h._multiplyBy(.5*(1-1/n)));i.style[o.DomUtil.TRANSFORM]=o.DomUtil.getTranslateString(l)+" scale("+n+") "},_reset:function(){var t=this._image,e=this._map.latLngToLayerPoint(this._bounds.getNorthWest()),i=this._map.latLngToLayerPoint(this._bounds.getSouthEast())._subtract(e);o.DomUtil.setPosition(t,e),t.style.width=i.x+"px",t.style.height=i.y+"px"},_onImageLoad:function(){this.fire("load")},_updateOpacity:function(){o.DomUtil.setOpacity(this._image,this.options.opacity)}}),o.imageOverlay=function(t,e,i){return new o.ImageOverlay(t,e,i)},o.Icon=o.Class.extend({options:{className:""},initialize:function(t){o.setOptions(this,t)},createIcon:function(t){return this._createIcon("icon",t)},createShadow:function(t){return this._createIcon("shadow",t)},_createIcon:function(t,e){var i=this._getIconUrl(t);if(!i){if("icon"===t)throw new Error("iconUrl not set in Icon options (see the docs).");return null}var n;return n=e&&"IMG"===e.tagName?this._createImg(i,e):this._createImg(i),this._setIconStyles(n,t),n},_setIconStyles:function(t,e){var i,n=this.options,s=o.point(n[e+"Size"]);i="shadow"===e?o.point(n.shadowAnchor||n.iconAnchor):o.point(n.iconAnchor),!i&&s&&(i=s.divideBy(2,!0)),t.className="leaflet-marker-"+e+" "+n.className,i&&(t.style.marginLeft=-i.x+"px",t.style.marginTop=-i.y+"px"),s&&(t.style.width=s.x+"px",t.style.height=s.y+"px")},_createImg:function(t,i){return i=i||e.createElement("img"),i.src=t,i},_getIconUrl:function(t){return o.Browser.retina&&this.options[t+"RetinaUrl"]?this.options[t+"RetinaUrl"]:this.options[t+"Url"]}}),o.icon=function(t){return new o.Icon(t)},o.Icon.Default=o.Icon.extend({options:{iconSize:[25,41],iconAnchor:[12,41],popupAnchor:[1,-34],shadowSize:[41,41]},_getIconUrl:function(t){var e=t+"Url";if(this.options[e])return this.options[e];o.Browser.retina&&"icon"===t&&(t+="-2x");var i=o.Icon.Default.imagePath;if(!i)throw new Error("Couldn't autodetect L.Icon.Default.imagePath, set it manually.");return i+"/marker-"+t+".png"}}),o.Icon.Default.imagePath=function(){var t,i,n,o,s,a=e.getElementsByTagName("script"),r=/[\/^]leaflet[\-\._]?([\w\-\._]*)\.js\??/;for(t=0,i=a.length;i>t;t++)if(n=a[t].src,o=n.match(r))return s=n.split(r)[0],(s?s+"/":"")+"images"}(),o.Marker=o.Class.extend({includes:o.Mixin.Events,options:{icon:new o.Icon.Default,title:"",alt:"",clickable:!0,draggable:!1,keyboard:!0,zIndexOffset:0,opacity:1,riseOnHover:!1,riseOffset:250},initialize:function(t,e){o.setOptions(this,e),this._latlng=o.latLng(t)},onAdd:function(t){this._map=t,t.on("viewreset",this.update,this),this._initIcon(),this.update(),this.fire("add"),t.options.zoomAnimation&&t.options.markerZoomAnimation&&t.on("zoomanim",this._animateZoom,this)},addTo:function(t){return t.addLayer(this),this},onRemove:function(t){this.dragging&&this.dragging.disable(),this._removeIcon(),this._removeShadow(),this.fire("remove"),t.off({viewreset:this.update,zoomanim:this._animateZoom},this),this._map=null},getLatLng:function(){return this._latlng},setLatLng:function(t){return this._latlng=o.latLng(t),this.update(),this.fire("move",{latlng:this._latlng})},setZIndexOffset:function(t){return this.options.zIndexOffset=t,this.update(),this},setIcon:function(t){return this.options.icon=t,this._map&&(this._initIcon(),this.update()),this._popup&&this.bindPopup(this._popup),this},update:function(){if(this._icon){var t=this._map.latLngToLayerPoint(this._latlng).round();this._setPos(t)}return this},_initIcon:function(){var t=this.options,e=this._map,i=e.options.zoomAnimation&&e.options.markerZoomAnimation,n=i?"leaflet-zoom-animated":"leaflet-zoom-hide",s=t.icon.createIcon(this._icon),a=!1;s!==this._icon&&(this._icon&&this._removeIcon(),a=!0,t.title&&(s.title=t.title),t.alt&&(s.alt=t.alt)),o.DomUtil.addClass(s,n),t.keyboard&&(s.tabIndex="0"),this._icon=s,this._initInteraction(),t.riseOnHover&&o.DomEvent.on(s,"mouseover",this._bringToFront,this).on(s,"mouseout",this._resetZIndex,this);var r=t.icon.createShadow(this._shadow),h=!1;r!==this._shadow&&(this._removeShadow(),h=!0),r&&o.DomUtil.addClass(r,n),this._shadow=r,t.opacity<1&&this._updateOpacity();var l=this._map._panes;a&&l.markerPane.appendChild(this._icon),r&&h&&l.shadowPane.appendChild(this._shadow)},_removeIcon:function(){this.options.riseOnHover&&o.DomEvent.off(this._icon,"mouseover",this._bringToFront).off(this._icon,"mouseout",this._resetZIndex),this._map._panes.markerPane.removeChild(this._icon),this._icon=null},_removeShadow:function(){this._shadow&&this._map._panes.shadowPane.removeChild(this._shadow),this._shadow=null},_setPos:function(t){o.DomUtil.setPosition(this._icon,t),this._shadow&&o.DomUtil.setPosition(this._shadow,t),this._zIndex=t.y+this.options.zIndexOffset,this._resetZIndex()},_updateZIndex:function(t){this._icon.style.zIndex=this._zIndex+t},_animateZoom:function(t){var e=this._map._latLngToNewLayerPoint(this._latlng,t.zoom,t.center).round();this._setPos(e)},_initInteraction:function(){if(this.options.clickable){var t=this._icon,e=["dblclick","mousedown","mouseover","mouseout","contextmenu"];o.DomUtil.addClass(t,"leaflet-clickable"),o.DomEvent.on(t,"click",this._onMouseClick,this),o.DomEvent.on(t,"keypress",this._onKeyPress,this);for(var i=0;is?(e.height=s+"px",o.DomUtil.addClass(t,a)):o.DomUtil.removeClass(t,a),this._containerWidth=this._container.offsetWidth},_updatePosition:function(){if(this._map){var t=this._map.latLngToLayerPoint(this._latlng),e=this._animated,i=o.point(this.options.offset);e&&o.DomUtil.setPosition(this._container,t),this._containerBottom=-i.y-(e?0:t.y),this._containerLeft=-Math.round(this._containerWidth/2)+i.x+(e?0:t.x),this._container.style.bottom=this._containerBottom+"px",this._container.style.left=this._containerLeft+"px"}},_zoomAnimation:function(t){var e=this._map._latLngToNewLayerPoint(this._latlng,t.zoom,t.center);o.DomUtil.setPosition(this._container,e)},_adjustPan:function(){if(this.options.autoPan){var t=this._map,e=this._container.offsetHeight,i=this._containerWidth,n=new o.Point(this._containerLeft,-e-this._containerBottom);this._animated&&n._add(o.DomUtil.getPosition(this._container));var s=t.layerPointToContainerPoint(n),a=o.point(this.options.autoPanPadding),r=o.point(this.options.autoPanPaddingTopLeft||a),h=o.point(this.options.autoPanPaddingBottomRight||a),l=t.getSize(),u=0,c=0;s.x+i+h.x>l.x&&(u=s.x+i-l.x+h.x),s.x-u-r.x<0&&(u=s.x-r.x),s.y+e+h.y>l.y&&(c=s.y+e-l.y+h.y),s.y-c-r.y<0&&(c=s.y-r.y),(u||c)&&t.fire("autopanstart").panBy([u,c])}},_onCloseButtonClick:function(t){this._close(),o.DomEvent.stop(t)}}),o.popup=function(t,e){return new o.Popup(t,e)},o.Map.include({openPopup:function(t,e,i){if(this.closePopup(),!(t instanceof o.Popup)){var n=t;t=new o.Popup(i).setLatLng(e).setContent(n)}return t._isOpen=!0,this._popup=t,this.addLayer(t)},closePopup:function(t){return t&&t!==this._popup||(t=this._popup,this._popup=null),t&&(this.removeLayer(t),t._isOpen=!1),this}}),o.Marker.include({openPopup:function(){return this._popup&&this._map&&!this._map.hasLayer(this._popup)&&(this._popup.setLatLng(this._latlng),this._map.openPopup(this._popup)),this},closePopup:function(){return this._popup&&this._popup._close(),this},togglePopup:function(){return this._popup&&(this._popup._isOpen?this.closePopup():this.openPopup()),this},bindPopup:function(t,e){var i=o.point(this.options.icon.options.popupAnchor||[0,0]);return i=i.add(o.Popup.prototype.options.offset),e&&e.offset&&(i=i.add(e.offset)),e=o.extend({offset:i},e),this._popupHandlersAdded||(this.on("click",this.togglePopup,this).on("remove",this.closePopup,this).on("move",this._movePopup,this),this._popupHandlersAdded=!0),t instanceof o.Popup?(o.setOptions(t,e),this._popup=t):this._popup=new o.Popup(e,this).setContent(t),this},setPopupContent:function(t){return this._popup&&this._popup.setContent(t),this},unbindPopup:function(){return this._popup&&(this._popup=null,this.off("click",this.togglePopup,this).off("remove",this.closePopup,this).off("move",this._movePopup,this),this._popupHandlersAdded=!1),this},getPopup:function(){return this._popup},_movePopup:function(t){this._popup.setLatLng(t.latlng)}}),o.LayerGroup=o.Class.extend({initialize:function(t){this._layers={};var e,i;if(t)for(e=0,i=t.length;i>e;e++)this.addLayer(t[e])},addLayer:function(t){var e=this.getLayerId(t);return this._layers[e]=t,this._map&&this._map.addLayer(t),this},removeLayer:function(t){var e=t in this._layers?t:this.getLayerId(t);return this._map&&this._layers[e]&&this._map.removeLayer(this._layers[e]),delete this._layers[e],this},hasLayer:function(t){return t?t in this._layers||this.getLayerId(t)in this._layers:!1},clearLayers:function(){return this.eachLayer(this.removeLayer,this),this},invoke:function(t){var e,i,n=Array.prototype.slice.call(arguments,1);for(e in this._layers)i=this._layers[e],i[t]&&i[t].apply(i,n);return this},onAdd:function(t){this._map=t,this.eachLayer(t.addLayer,t)},onRemove:function(t){this.eachLayer(t.removeLayer,t),this._map=null},addTo:function(t){return t.addLayer(this),this},eachLayer:function(t,e){for(var i in this._layers)t.call(e,this._layers[i]);return this},getLayer:function(t){return this._layers[t]},getLayers:function(){var t=[];for(var e in this._layers)t.push(this._layers[e]);return t},setZIndex:function(t){return this.invoke("setZIndex",t)},getLayerId:function(t){return o.stamp(t)}}),o.layerGroup=function(t){return new o.LayerGroup(t)},o.FeatureGroup=o.LayerGroup.extend({includes:o.Mixin.Events,statics:{EVENTS:"click dblclick mouseover mouseout mousemove contextmenu popupopen popupclose"},addLayer:function(t){return this.hasLayer(t)?this:("on"in t&&t.on(o.FeatureGroup.EVENTS,this._propagateEvent,this),o.LayerGroup.prototype.addLayer.call(this,t),this._popupContent&&t.bindPopup&&t.bindPopup(this._popupContent,this._popupOptions),this.fire("layeradd",{layer:t}))},removeLayer:function(t){return this.hasLayer(t)?(t in this._layers&&(t=this._layers[t]),t.off(o.FeatureGroup.EVENTS,this._propagateEvent,this),o.LayerGroup.prototype.removeLayer.call(this,t),this._popupContent&&this.invoke("unbindPopup"),this.fire("layerremove",{layer:t})):this},bindPopup:function(t,e){return this._popupContent=t,this._popupOptions=e,this.invoke("bindPopup",t,e)},openPopup:function(t){for(var e in this._layers){this._layers[e].openPopup(t);break}return this},setStyle:function(t){return this.invoke("setStyle",t)},bringToFront:function(){return this.invoke("bringToFront")},bringToBack:function(){return this.invoke("bringToBack")},getBounds:function(){var t=new o.LatLngBounds;return this.eachLayer(function(e){t.extend(e instanceof o.Marker?e.getLatLng():e.getBounds())}),t},_propagateEvent:function(t){t=o.extend({},t,{layer:t.target,target:this}),this.fire(t.type,t)}}),o.featureGroup=function(t){return new o.FeatureGroup(t)},o.Path=o.Class.extend({includes:[o.Mixin.Events],statics:{CLIP_PADDING:function(){var e=o.Browser.mobile?1280:2e3,i=(e/Math.max(t.outerWidth,t.outerHeight)-1)/2;return Math.max(0,Math.min(.5,i))}()},options:{stroke:!0,color:"#0033ff",dashArray:null,lineCap:null,lineJoin:null,weight:5,opacity:.5,fill:!1,fillColor:null,fillOpacity:.2,clickable:!0},initialize:function(t){o.setOptions(this,t)},onAdd:function(t){this._map=t,this._container||(this._initElements(),this._initEvents()),this.projectLatlngs(),this._updatePath(),this._container&&this._map._pathRoot.appendChild(this._container),this.fire("add"),t.on({viewreset:this.projectLatlngs,moveend:this._updatePath},this)},addTo:function(t){return t.addLayer(this),this},onRemove:function(t){t._pathRoot.removeChild(this._container),this.fire("remove"),this._map=null,o.Browser.vml&&(this._container=null,this._stroke=null,this._fill=null),t.off({viewreset:this.projectLatlngs,moveend:this._updatePath},this)},projectLatlngs:function(){},setStyle:function(t){return o.setOptions(this,t),this._container&&this._updateStyle(),this},redraw:function(){return this._map&&(this.projectLatlngs(),this._updatePath()),this}}),o.Map.include({_updatePathViewport:function(){var t=o.Path.CLIP_PADDING,e=this.getSize(),i=o.DomUtil.getPosition(this._mapPane),n=i.multiplyBy(-1)._subtract(e.multiplyBy(t)._round()),s=n.add(e.multiplyBy(1+2*t)._round());this._pathViewport=new o.Bounds(n,s)}}),o.Path.SVG_NS="http://www.w3.org/2000/svg",o.Browser.svg=!(!e.createElementNS||!e.createElementNS(o.Path.SVG_NS,"svg").createSVGRect),o.Path=o.Path.extend({statics:{SVG:o.Browser.svg},bringToFront:function(){var t=this._map._pathRoot,e=this._container;return e&&t.lastChild!==e&&t.appendChild(e),this},bringToBack:function(){var t=this._map._pathRoot,e=this._container,i=t.firstChild;return e&&i!==e&&t.insertBefore(e,i),this},getPathString:function(){},_createElement:function(t){return e.createElementNS(o.Path.SVG_NS,t)},_initElements:function(){this._map._initPathRoot(),this._initPath(),this._initStyle()},_initPath:function(){this._container=this._createElement("g"),this._path=this._createElement("path"),this.options.className&&o.DomUtil.addClass(this._path,this.options.className),this._container.appendChild(this._path)},_initStyle:function(){this.options.stroke&&(this._path.setAttribute("stroke-linejoin","round"),this._path.setAttribute("stroke-linecap","round")),this.options.fill&&this._path.setAttribute("fill-rule","evenodd"),this.options.pointerEvents&&this._path.setAttribute("pointer-events",this.options.pointerEvents),this.options.clickable||this.options.pointerEvents||this._path.setAttribute("pointer-events","none"),this._updateStyle()},_updateStyle:function(){this.options.stroke?(this._path.setAttribute("stroke",this.options.color),this._path.setAttribute("stroke-opacity",this.options.opacity),this._path.setAttribute("stroke-width",this.options.weight),this.options.dashArray?this._path.setAttribute("stroke-dasharray",this.options.dashArray):this._path.removeAttribute("stroke-dasharray"),this.options.lineCap&&this._path.setAttribute("stroke-linecap",this.options.lineCap),this.options.lineJoin&&this._path.setAttribute("stroke-linejoin",this.options.lineJoin)):this._path.setAttribute("stroke","none"),this.options.fill?(this._path.setAttribute("fill",this.options.fillColor||this.options.color),this._path.setAttribute("fill-opacity",this.options.fillOpacity)):this._path.setAttribute("fill","none")},_updatePath:function(){var t=this.getPathString();t||(t="M0 0"),this._path.setAttribute("d",t)},_initEvents:function(){if(this.options.clickable){(o.Browser.svg||!o.Browser.vml)&&o.DomUtil.addClass(this._path,"leaflet-clickable"),o.DomEvent.on(this._container,"click",this._onMouseClick,this);for(var t=["dblclick","mousedown","mouseover","mouseout","mousemove","contextmenu"],e=0;e';var i=t.firstChild;return i.style.behavior="url(#default#VML)",i&&"object"==typeof i.adj}catch(n){return!1}}(),o.Path=o.Browser.svg||!o.Browser.vml?o.Path:o.Path.extend({statics:{VML:!0,CLIP_PADDING:.02},_createElement:function(){try{return e.namespaces.add("lvml","urn:schemas-microsoft-com:vml"),function(t){return e.createElement("')}}catch(t){return function(t){return e.createElement("<"+t+' xmlns="urn:schemas-microsoft.com:vml" class="lvml">')}}}(),_initPath:function(){var t=this._container=this._createElement("shape");o.DomUtil.addClass(t,"leaflet-vml-shape"+(this.options.className?" "+this.options.className:"")),this.options.clickable&&o.DomUtil.addClass(t,"leaflet-clickable"),t.coordsize="1 1",this._path=this._createElement("path"),t.appendChild(this._path),this._map._pathRoot.appendChild(t)},_initStyle:function(){this._updateStyle()},_updateStyle:function(){var t=this._stroke,e=this._fill,i=this.options,n=this._container;n.stroked=i.stroke,n.filled=i.fill,i.stroke?(t||(t=this._stroke=this._createElement("stroke"),t.endcap="round",n.appendChild(t)),t.weight=i.weight+"px",t.color=i.color,t.opacity=i.opacity,t.dashStyle=i.dashArray?o.Util.isArray(i.dashArray)?i.dashArray.join(" "):i.dashArray.replace(/( *, *)/g," "):"",i.lineCap&&(t.endcap=i.lineCap.replace("butt","flat")),i.lineJoin&&(t.joinstyle=i.lineJoin)):t&&(n.removeChild(t),this._stroke=null),i.fill?(e||(e=this._fill=this._createElement("fill"),n.appendChild(e)),e.color=i.fillColor||i.color,e.opacity=i.fillOpacity):e&&(n.removeChild(e),this._fill=null)},_updatePath:function(){var t=this._container.style;t.display="none",this._path.v=this.getPathString()+" ",t.display=""}}),o.Map.include(o.Browser.svg||!o.Browser.vml?{}:{_initPathRoot:function(){if(!this._pathRoot){var t=this._pathRoot=e.createElement("div");t.className="leaflet-vml-container",this._panes.overlayPane.appendChild(t),this.on("moveend",this._updatePathViewport),this._updatePathViewport()}}}),o.Browser.canvas=function(){return!!e.createElement("canvas").getContext}(),o.Path=o.Path.SVG&&!t.L_PREFER_CANVAS||!o.Browser.canvas?o.Path:o.Path.extend({statics:{CANVAS:!0,SVG:!1},redraw:function(){return this._map&&(this.projectLatlngs(),this._requestUpdate()),this},setStyle:function(t){return o.setOptions(this,t),this._map&&(this._updateStyle(),this._requestUpdate()),this},onRemove:function(t){t.off("viewreset",this.projectLatlngs,this).off("moveend",this._updatePath,this),this.options.clickable&&(this._map.off("click",this._onClick,this),this._map.off("mousemove",this._onMouseMove,this)),this._requestUpdate(),this._map=null},_requestUpdate:function(){this._map&&!o.Path._updateRequest&&(o.Path._updateRequest=o.Util.requestAnimFrame(this._fireMapMoveEnd,this._map))},_fireMapMoveEnd:function(){o.Path._updateRequest=null,this.fire("moveend")},_initElements:function(){this._map._initPathRoot(),this._ctx=this._map._canvasCtx},_updateStyle:function(){var t=this.options;t.stroke&&(this._ctx.lineWidth=t.weight,this._ctx.strokeStyle=t.color),t.fill&&(this._ctx.fillStyle=t.fillColor||t.color)},_drawPath:function(){var t,e,i,n,s,a;for(this._ctx.beginPath(),t=0,i=this._parts.length;i>t;t++){for(e=0,n=this._parts[t].length;n>e;e++)s=this._parts[t][e],a=(0===e?"move":"line")+"To",this._ctx[a](s.x,s.y);this instanceof o.Polygon&&this._ctx.closePath()}},_checkIfEmpty:function(){return!this._parts.length},_updatePath:function(){if(!this._checkIfEmpty()){var t=this._ctx,e=this.options;this._drawPath(),t.save(),this._updateStyle(),e.fill&&(t.globalAlpha=e.fillOpacity,t.fill()),e.stroke&&(t.globalAlpha=e.opacity,t.stroke()),t.restore()}},_initEvents:function(){this.options.clickable&&(this._map.on("mousemove",this._onMouseMove,this),this._map.on("click",this._onClick,this))},_onClick:function(t){this._containsPoint(t.layerPoint)&&this.fire("click",t)},_onMouseMove:function(t){this._map&&!this._map._animatingZoom&&(this._containsPoint(t.layerPoint)?(this._ctx.canvas.style.cursor="pointer",this._mouseInside=!0,this.fire("mouseover",t)):this._mouseInside&&(this._ctx.canvas.style.cursor="",this._mouseInside=!1,this.fire("mouseout",t)))}}),o.Map.include(o.Path.SVG&&!t.L_PREFER_CANVAS||!o.Browser.canvas?{}:{_initPathRoot:function(){var t,i=this._pathRoot;i||(i=this._pathRoot=e.createElement("canvas"),i.style.position="absolute",t=this._canvasCtx=i.getContext("2d"),t.lineCap="round",t.lineJoin="round",this._panes.overlayPane.appendChild(i),this.options.zoomAnimation&&(this._pathRoot.className="leaflet-zoom-animated",this.on("zoomanim",this._animatePathZoom),this.on("zoomend",this._endPathZoom)),this.on("moveend",this._updateCanvasViewport),this._updateCanvasViewport())},_updateCanvasViewport:function(){if(!this._pathZooming){this._updatePathViewport();var t=this._pathViewport,e=t.min,i=t.max.subtract(e),n=this._pathRoot;o.DomUtil.setPosition(n,e),n.width=i.x,n.height=i.y,n.getContext("2d").translate(-e.x,-e.y)}}}),o.LineUtil={simplify:function(t,e){if(!e||!t.length)return t.slice();var i=e*e;return t=this._reducePoints(t,i),t=this._simplifyDP(t,i)},pointToSegmentDistance:function(t,e,i){return Math.sqrt(this._sqClosestPointOnSegment(t,e,i,!0))},closestPointOnSegment:function(t,e,i){return this._sqClosestPointOnSegment(t,e,i)},_simplifyDP:function(t,e){var n=t.length,o=typeof Uint8Array!=i+""?Uint8Array:Array,s=new o(n);s[0]=s[n-1]=1,this._simplifyDPStep(t,s,e,0,n-1);var a,r=[];for(a=0;n>a;a++)s[a]&&r.push(t[a]);return r},_simplifyDPStep:function(t,e,i,n,o){var s,a,r,h=0;for(a=n+1;o-1>=a;a++)r=this._sqClosestPointOnSegment(t[a],t[n],t[o],!0),r>h&&(s=a,h=r);h>i&&(e[s]=1,this._simplifyDPStep(t,e,i,n,s),this._simplifyDPStep(t,e,i,s,o))},_reducePoints:function(t,e){for(var i=[t[0]],n=1,o=0,s=t.length;s>n;n++)this._sqDist(t[n],t[o])>e&&(i.push(t[n]),o=n);return s-1>o&&i.push(t[s-1]),i},clipSegment:function(t,e,i,n){var o,s,a,r=n?this._lastCode:this._getBitCode(t,i),h=this._getBitCode(e,i);for(this._lastCode=h;;){if(!(r|h))return[t,e];if(r&h)return!1;o=r||h,s=this._getEdgeIntersection(t,e,o,i),a=this._getBitCode(s,i),o===r?(t=s,r=a):(e=s,h=a)}},_getEdgeIntersection:function(t,e,i,n){var s=e.x-t.x,a=e.y-t.y,r=n.min,h=n.max;return 8&i?new o.Point(t.x+s*(h.y-t.y)/a,h.y):4&i?new o.Point(t.x+s*(r.y-t.y)/a,r.y):2&i?new o.Point(h.x,t.y+a*(h.x-t.x)/s):1&i?new o.Point(r.x,t.y+a*(r.x-t.x)/s):void 0},_getBitCode:function(t,e){var i=0;return t.xe.max.x&&(i|=2),t.ye.max.y&&(i|=8),i},_sqDist:function(t,e){var i=e.x-t.x,n=e.y-t.y;return i*i+n*n},_sqClosestPointOnSegment:function(t,e,i,n){var s,a=e.x,r=e.y,h=i.x-a,l=i.y-r,u=h*h+l*l;return u>0&&(s=((t.x-a)*h+(t.y-r)*l)/u,s>1?(a=i.x,r=i.y):s>0&&(a+=h*s,r+=l*s)),h=t.x-a,l=t.y-r,n?h*h+l*l:new o.Point(a,r)}},o.Polyline=o.Path.extend({initialize:function(t,e){o.Path.prototype.initialize.call(this,e),this._latlngs=this._convertLatLngs(t)},options:{smoothFactor:1,noClip:!1},projectLatlngs:function(){this._originalPoints=[];for(var t=0,e=this._latlngs.length;e>t;t++)this._originalPoints[t]=this._map.latLngToLayerPoint(this._latlngs[t])},getPathString:function(){for(var t=0,e=this._parts.length,i="";e>t;t++)i+=this._getPathPartStr(this._parts[t]);return i},getLatLngs:function(){return this._latlngs},setLatLngs:function(t){return this._latlngs=this._convertLatLngs(t),this.redraw()},addLatLng:function(t){return this._latlngs.push(o.latLng(t)),this.redraw()},spliceLatLngs:function(){var t=[].splice.apply(this._latlngs,arguments);return this._convertLatLngs(this._latlngs,!0),this.redraw(),t},closestLayerPoint:function(t){for(var e,i,n=1/0,s=this._parts,a=null,r=0,h=s.length;h>r;r++)for(var l=s[r],u=1,c=l.length;c>u;u++){e=l[u-1],i=l[u];var d=o.LineUtil._sqClosestPointOnSegment(t,e,i,!0);n>d&&(n=d,a=o.LineUtil._sqClosestPointOnSegment(t,e,i))}return a&&(a.distance=Math.sqrt(n)),a},getBounds:function(){return new o.LatLngBounds(this.getLatLngs())},_convertLatLngs:function(t,e){var i,n,s=e?t:[];for(i=0,n=t.length;n>i;i++){if(o.Util.isArray(t[i])&&"number"!=typeof t[i][0])return;s[i]=o.latLng(t[i])}return s},_initEvents:function(){o.Path.prototype._initEvents.call(this)},_getPathPartStr:function(t){for(var e,i=o.Path.VML,n=0,s=t.length,a="";s>n;n++)e=t[n],i&&e._round(),a+=(n?"L":"M")+e.x+" "+e.y;return a},_clipPoints:function(){var t,e,i,n=this._originalPoints,s=n.length;if(this.options.noClip)return this._parts=[n],void 0;this._parts=[];var a=this._parts,r=this._map._pathViewport,h=o.LineUtil;for(t=0,e=0;s-1>t;t++)i=h.clipSegment(n[t],n[t+1],r,t),i&&(a[e]=a[e]||[],a[e].push(i[0]),(i[1]!==n[t+1]||t===s-2)&&(a[e].push(i[1]),e++))},_simplifyPoints:function(){for(var t=this._parts,e=o.LineUtil,i=0,n=t.length;n>i;i++)t[i]=e.simplify(t[i],this.options.smoothFactor)},_updatePath:function(){this._map&&(this._clipPoints(),this._simplifyPoints(),o.Path.prototype._updatePath.call(this))}}),o.polyline=function(t,e){return new o.Polyline(t,e)},o.PolyUtil={},o.PolyUtil.clipPolygon=function(t,e){var i,n,s,a,r,h,l,u,c,d=[1,4,2,8],p=o.LineUtil;for(n=0,l=t.length;l>n;n++)t[n]._code=p._getBitCode(t[n],e);for(a=0;4>a;a++){for(u=d[a],i=[],n=0,l=t.length,s=l-1;l>n;s=n++)r=t[n],h=t[s],r._code&u?h._code&u||(c=p._getEdgeIntersection(h,r,u,e),c._code=p._getBitCode(c,e),i.push(c)):(h._code&u&&(c=p._getEdgeIntersection(h,r,u,e),c._code=p._getBitCode(c,e),i.push(c)),i.push(r));t=i}return t},o.Polygon=o.Polyline.extend({options:{fill:!0},initialize:function(t,e){o.Polyline.prototype.initialize.call(this,t,e),this._initWithHoles(t)},_initWithHoles:function(t){var e,i,n;if(t&&o.Util.isArray(t[0])&&"number"!=typeof t[0][0])for(this._latlngs=this._convertLatLngs(t[0]),this._holes=t.slice(1),e=0,i=this._holes.length;i>e;e++)n=this._holes[e]=this._convertLatLngs(this._holes[e]),n[0].equals(n[n.length-1])&&n.pop();t=this._latlngs,t.length>=2&&t[0].equals(t[t.length-1])&&t.pop()},projectLatlngs:function(){if(o.Polyline.prototype.projectLatlngs.call(this),this._holePoints=[],this._holes){var t,e,i,n;for(t=0,i=this._holes.length;i>t;t++)for(this._holePoints[t]=[],e=0,n=this._holes[t].length;n>e;e++)this._holePoints[t][e]=this._map.latLngToLayerPoint(this._holes[t][e])}},setLatLngs:function(t){return t&&o.Util.isArray(t[0])&&"number"!=typeof t[0][0]?(this._initWithHoles(t),this.redraw()):o.Polyline.prototype.setLatLngs.call(this,t)},_clipPoints:function(){var t=this._originalPoints,e=[];if(this._parts=[t].concat(this._holePoints),!this.options.noClip){for(var i=0,n=this._parts.length;n>i;i++){var s=o.PolyUtil.clipPolygon(this._parts[i],this._map._pathViewport);s.length&&e.push(s)}this._parts=e}},_getPathPartStr:function(t){var e=o.Polyline.prototype._getPathPartStr.call(this,t);return e+(o.Browser.svg?"z":"x")}}),o.polygon=function(t,e){return new o.Polygon(t,e)},function(){function t(t){return o.FeatureGroup.extend({initialize:function(t,e){this._layers={},this._options=e,this.setLatLngs(t)},setLatLngs:function(e){var i=0,n=e.length;for(this.eachLayer(function(t){n>i?t.setLatLngs(e[i++]):this.removeLayer(t)},this);n>i;)this.addLayer(new t(e[i++],this._options));return this},getLatLngs:function(){var t=[];return this.eachLayer(function(e){t.push(e.getLatLngs())}),t}})}o.MultiPolyline=t(o.Polyline),o.MultiPolygon=t(o.Polygon),o.multiPolyline=function(t,e){return new o.MultiPolyline(t,e)},o.multiPolygon=function(t,e){return new o.MultiPolygon(t,e)}}(),o.Rectangle=o.Polygon.extend({initialize:function(t,e){o.Polygon.prototype.initialize.call(this,this._boundsToLatLngs(t),e)},setBounds:function(t){this.setLatLngs(this._boundsToLatLngs(t))},_boundsToLatLngs:function(t){return t=o.latLngBounds(t),[t.getSouthWest(),t.getNorthWest(),t.getNorthEast(),t.getSouthEast()]}}),o.rectangle=function(t,e){return new o.Rectangle(t,e)},o.Circle=o.Path.extend({initialize:function(t,e,i){o.Path.prototype.initialize.call(this,i),this._latlng=o.latLng(t),this._mRadius=e},options:{fill:!0},setLatLng:function(t){return this._latlng=o.latLng(t),this.redraw()},setRadius:function(t){return this._mRadius=t,this.redraw()},projectLatlngs:function(){var t=this._getLngRadius(),e=this._latlng,i=this._map.latLngToLayerPoint([e.lat,e.lng-t]);this._point=this._map.latLngToLayerPoint(e),this._radius=Math.max(this._point.x-i.x,1)},getBounds:function(){var t=this._getLngRadius(),e=this._mRadius/40075017*360,i=this._latlng;return new o.LatLngBounds([i.lat-e,i.lng-t],[i.lat+e,i.lng+t])},getLatLng:function(){return this._latlng},getPathString:function(){var t=this._point,e=this._radius;return this._checkIfEmpty()?"":o.Browser.svg?"M"+t.x+","+(t.y-e)+"A"+e+","+e+",0,1,1,"+(t.x-.1)+","+(t.y-e)+" z":(t._round(),e=Math.round(e),"AL "+t.x+","+t.y+" "+e+","+e+" 0,23592600")},getRadius:function(){return this._mRadius},_getLatRadius:function(){return this._mRadius/40075017*360},_getLngRadius:function(){return this._getLatRadius()/Math.cos(o.LatLng.DEG_TO_RAD*this._latlng.lat)},_checkIfEmpty:function(){if(!this._map)return!1;var t=this._map._pathViewport,e=this._radius,i=this._point;return i.x-e>t.max.x||i.y-e>t.max.y||i.x+ei;i++)for(l=this._parts[i],n=0,r=l.length,s=r-1;r>n;s=n++)if((e||0!==n)&&(h=o.LineUtil.pointToSegmentDistance(t,l[s],l[n]),u>=h))return!0;return!1}}:{}),o.Polygon.include(o.Path.CANVAS?{_containsPoint:function(t){var e,i,n,s,a,r,h,l,u=!1;if(o.Polyline.prototype._containsPoint.call(this,t,!0))return!0;for(s=0,h=this._parts.length;h>s;s++)for(e=this._parts[s],a=0,l=e.length,r=l-1;l>a;r=a++)i=e[a],n=e[r],i.y>t.y!=n.y>t.y&&t.x<(n.x-i.x)*(t.y-i.y)/(n.y-i.y)+i.x&&(u=!u);return u}}:{}),o.Circle.include(o.Path.CANVAS?{_drawPath:function(){var t=this._point;this._ctx.beginPath(),this._ctx.arc(t.x,t.y,this._radius,0,2*Math.PI,!1)},_containsPoint:function(t){var e=this._point,i=this.options.stroke?this.options.weight/2:0;return t.distanceTo(e)<=this._radius+i}}:{}),o.CircleMarker.include(o.Path.CANVAS?{_updateStyle:function(){o.Path.prototype._updateStyle.call(this)}}:{}),o.GeoJSON=o.FeatureGroup.extend({initialize:function(t,e){o.setOptions(this,e),this._layers={},t&&this.addData(t)},addData:function(t){var e,i,n,s=o.Util.isArray(t)?t:t.features;if(s){for(e=0,i=s.length;i>e;e++)n=s[e],(n.geometries||n.geometry||n.features||n.coordinates)&&this.addData(s[e]);return this}var a=this.options;if(!a.filter||a.filter(t)){var r=o.GeoJSON.geometryToLayer(t,a.pointToLayer,a.coordsToLatLng,a);return r.feature=o.GeoJSON.asFeature(t),r.defaultOptions=r.options,this.resetStyle(r),a.onEachFeature&&a.onEachFeature(t,r),this.addLayer(r)}},resetStyle:function(t){var e=this.options.style;e&&(o.Util.extend(t.options,t.defaultOptions),this._setLayerStyle(t,e))},setStyle:function(t){this.eachLayer(function(e){this._setLayerStyle(e,t)},this)},_setLayerStyle:function(t,e){"function"==typeof e&&(e=e(t.feature)),t.setStyle&&t.setStyle(e)}}),o.extend(o.GeoJSON,{geometryToLayer:function(t,e,i,n){var s,a,r,h,l="Feature"===t.type?t.geometry:t,u=l.coordinates,c=[];switch(i=i||this.coordsToLatLng,l.type){case"Point":return s=i(u),e?e(t,s):new o.Marker(s);case"MultiPoint":for(r=0,h=u.length;h>r;r++)s=i(u[r]),c.push(e?e(t,s):new o.Marker(s));return new o.FeatureGroup(c);case"LineString":return a=this.coordsToLatLngs(u,0,i),new o.Polyline(a,n);case"Polygon":if(2===u.length&&!u[1].length)throw new Error("Invalid GeoJSON object.");return a=this.coordsToLatLngs(u,1,i),new o.Polygon(a,n);case"MultiLineString":return a=this.coordsToLatLngs(u,1,i),new o.MultiPolyline(a,n);case"MultiPolygon":return a=this.coordsToLatLngs(u,2,i),new o.MultiPolygon(a,n);case"GeometryCollection":for(r=0,h=l.geometries.length;h>r;r++)c.push(this.geometryToLayer({geometry:l.geometries[r],type:"Feature",properties:t.properties},e,i,n));return new o.FeatureGroup(c);default:throw new Error("Invalid GeoJSON object.")}},coordsToLatLng:function(t){return new o.LatLng(t[1],t[0],t[2])},coordsToLatLngs:function(t,e,i){var n,o,s,a=[];for(o=0,s=t.length;s>o;o++)n=e?this.coordsToLatLngs(t[o],e-1,i):(i||this.coordsToLatLng)(t[o]),a.push(n);return a},latLngToCoords:function(t){var e=[t.lng,t.lat];return t.alt!==i&&e.push(t.alt),e},latLngsToCoords:function(t){for(var e=[],i=0,n=t.length;n>i;i++)e.push(o.GeoJSON.latLngToCoords(t[i]));return e},getFeature:function(t,e){return t.feature?o.extend({},t.feature,{geometry:e}):o.GeoJSON.asFeature(e)},asFeature:function(t){return"Feature"===t.type?t:{type:"Feature",properties:{},geometry:t}}});var a={toGeoJSON:function(){return o.GeoJSON.getFeature(this,{type:"Point",coordinates:o.GeoJSON.latLngToCoords(this.getLatLng())})}};o.Marker.include(a),o.Circle.include(a),o.CircleMarker.include(a),o.Polyline.include({toGeoJSON:function(){return o.GeoJSON.getFeature(this,{type:"LineString",coordinates:o.GeoJSON.latLngsToCoords(this.getLatLngs())})}}),o.Polygon.include({toGeoJSON:function(){var t,e,i,n=[o.GeoJSON.latLngsToCoords(this.getLatLngs())];if(n[0].push(n[0][0]),this._holes)for(t=0,e=this._holes.length;e>t;t++)i=o.GeoJSON.latLngsToCoords(this._holes[t]),i.push(i[0]),n.push(i);return o.GeoJSON.getFeature(this,{type:"Polygon",coordinates:n})}}),function(){function t(t){return function(){var e=[];return this.eachLayer(function(t){e.push(t.toGeoJSON().geometry.coordinates)}),o.GeoJSON.getFeature(this,{type:t,coordinates:e})}}o.MultiPolyline.include({toGeoJSON:t("MultiLineString")}),o.MultiPolygon.include({toGeoJSON:t("MultiPolygon")}),o.LayerGroup.include({toGeoJSON:function(){var e,i=this.feature&&this.feature.geometry,n=[];if(i&&"MultiPoint"===i.type)return t("MultiPoint").call(this);var s=i&&"GeometryCollection"===i.type;return this.eachLayer(function(t){t.toGeoJSON&&(e=t.toGeoJSON(),n.push(s?e.geometry:o.GeoJSON.asFeature(e)))}),s?o.GeoJSON.getFeature(this,{geometries:n,type:"GeometryCollection"}):{type:"FeatureCollection",features:n}}})}(),o.geoJson=function(t,e){return new o.GeoJSON(t,e)},o.DomEvent={addListener:function(t,e,i,n){var s,a,r,h=o.stamp(i),l="_leaflet_"+e+h;return t[l]?this:(s=function(e){return i.call(n||t,e||o.DomEvent._getEvent())},o.Browser.pointer&&0===e.indexOf("touch")?this.addPointerListener(t,e,s,h):(o.Browser.touch&&"dblclick"===e&&this.addDoubleTapListener&&this.addDoubleTapListener(t,s,h),"addEventListener"in t?"mousewheel"===e?(t.addEventListener("DOMMouseScroll",s,!1),t.addEventListener(e,s,!1)):"mouseenter"===e||"mouseleave"===e?(a=s,r="mouseenter"===e?"mouseover":"mouseout",s=function(e){return o.DomEvent._checkMouse(t,e)?a(e):void 0},t.addEventListener(r,s,!1)):"click"===e&&o.Browser.android?(a=s,s=function(t){return o.DomEvent._filterClick(t,a)},t.addEventListener(e,s,!1)):t.addEventListener(e,s,!1):"attachEvent"in t&&t.attachEvent("on"+e,s),t[l]=s,this))},removeListener:function(t,e,i){var n=o.stamp(i),s="_leaflet_"+e+n,a=t[s];return a?(o.Browser.pointer&&0===e.indexOf("touch")?this.removePointerListener(t,e,n):o.Browser.touch&&"dblclick"===e&&this.removeDoubleTapListener?this.removeDoubleTapListener(t,n):"removeEventListener"in t?"mousewheel"===e?(t.removeEventListener("DOMMouseScroll",a,!1),t.removeEventListener(e,a,!1)):"mouseenter"===e||"mouseleave"===e?t.removeEventListener("mouseenter"===e?"mouseover":"mouseout",a,!1):t.removeEventListener(e,a,!1):"detachEvent"in t&&t.detachEvent("on"+e,a),t[s]=null,this):this},stopPropagation:function(t){return t.stopPropagation?t.stopPropagation():t.cancelBubble=!0,o.DomEvent._skipped(t),this},disableScrollPropagation:function(t){var e=o.DomEvent.stopPropagation;return o.DomEvent.on(t,"mousewheel",e).on(t,"MozMousePixelScroll",e)},disableClickPropagation:function(t){for(var e=o.DomEvent.stopPropagation,i=o.Draggable.START.length-1;i>=0;i--)o.DomEvent.on(t,o.Draggable.START[i],e);return o.DomEvent.on(t,"click",o.DomEvent._fakeStop).on(t,"dblclick",e)},preventDefault:function(t){return t.preventDefault?t.preventDefault():t.returnValue=!1,this},stop:function(t){return o.DomEvent.preventDefault(t).stopPropagation(t)},getMousePosition:function(t,i){var n=e.body,s=e.documentElement,a=o.DomUtil.documentIsLtr()?t.pageX?t.pageX-n.scrollLeft-s.scrollLeft:t.clientX:o.Browser.gecko?t.pageX-n.scrollLeft-s.scrollLeft:t.pageX?t.pageX-n.scrollLeft+s.scrollLeft:t.clientX,r=t.pageY?t.pageY-n.scrollTop-s.scrollTop:t.clientY,h=new o.Point(a,r);if(!i)return h;var l=i.getBoundingClientRect(),u=l.left-i.clientLeft,c=l.top-i.clientTop;return h._subtract(new o.Point(u,c))},getWheelDelta:function(t){var e=0;return t.wheelDelta&&(e=t.wheelDelta/120),t.detail&&(e=-t.detail/3),e},_skipEvents:{},_fakeStop:function(t){o.DomEvent._skipEvents[t.type]=!0},_skipped:function(t){var e=this._skipEvents[t.type];return this._skipEvents[t.type]=!1,e},_checkMouse:function(t,e){var i=e.relatedTarget;if(!i)return!0;try{for(;i&&i!==t;)i=i.parentNode}catch(n){return!1}return i!==t},_getEvent:function(){var e=t.event;if(!e)for(var i=arguments.callee.caller;i&&(e=i.arguments[0],!e||t.Event!==e.constructor);)i=i.caller;return e},_filterClick:function(t,e){var i=t.timeStamp||t.originalEvent.timeStamp,n=o.DomEvent._lastClick&&i-o.DomEvent._lastClick;return n&&n>100&&1e3>n||t.target._simulatedClick&&!t._simulated?(o.DomEvent.stop(t),void 0):(o.DomEvent._lastClick=i,e(t))}},o.DomEvent.on=o.DomEvent.addListener,o.DomEvent.off=o.DomEvent.removeListener,o.Draggable=o.Class.extend({includes:o.Mixin.Events,statics:{START:o.Browser.touch?["touchstart","mousedown"]:["mousedown"],END:{mousedown:"mouseup",touchstart:"touchend",pointerdown:"touchend",MSPointerDown:"touchend"},MOVE:{mousedown:"mousemove",touchstart:"touchmove",pointerdown:"touchmove",MSPointerDown:"touchmove"}},initialize:function(t,e){this._element=t,this._dragStartTarget=e||t},enable:function(){if(!this._enabled){for(var t=o.Draggable.START.length-1;t>=0;t--)o.DomEvent.on(this._dragStartTarget,o.Draggable.START[t],this._onDown,this);this._enabled=!0}},disable:function(){if(this._enabled){for(var t=o.Draggable.START.length-1;t>=0;t--)o.DomEvent.off(this._dragStartTarget,o.Draggable.START[t],this._onDown,this);this._enabled=!1,this._moved=!1}},_onDown:function(t){if(this._moved=!1,!(t.shiftKey||1!==t.which&&1!==t.button&&!t.touches||(o.DomEvent.stopPropagation(t),o.Draggable._disabled||(o.DomUtil.disableImageDrag(),o.DomUtil.disableTextSelection(),this._moving)))){var i=t.touches?t.touches[0]:t;this._startPoint=new o.Point(i.clientX,i.clientY),this._startPos=this._newPos=o.DomUtil.getPosition(this._element),o.DomEvent.on(e,o.Draggable.MOVE[t.type],this._onMove,this).on(e,o.Draggable.END[t.type],this._onUp,this)}},_onMove:function(t){if(t.touches&&t.touches.length>1)return this._moved=!0,void 0;var i=t.touches&&1===t.touches.length?t.touches[0]:t,n=new o.Point(i.clientX,i.clientY),s=n.subtract(this._startPoint);(s.x||s.y)&&(o.DomEvent.preventDefault(t),this._moved||(this.fire("dragstart"),this._moved=!0,this._startPos=o.DomUtil.getPosition(this._element).subtract(s),o.DomUtil.addClass(e.body,"leaflet-dragging"),o.DomUtil.addClass(t.target||t.srcElement,"leaflet-drag-target")),this._newPos=this._startPos.add(s),this._moving=!0,o.Util.cancelAnimFrame(this._animRequest),this._animRequest=o.Util.requestAnimFrame(this._updatePosition,this,!0,this._dragStartTarget))},_updatePosition:function(){this.fire("predrag"),o.DomUtil.setPosition(this._element,this._newPos),this.fire("drag")},_onUp:function(t){o.DomUtil.removeClass(e.body,"leaflet-dragging"),o.DomUtil.removeClass(t.target||t.srcElement,"leaflet-drag-target");for(var i in o.Draggable.MOVE)o.DomEvent.off(e,o.Draggable.MOVE[i],this._onMove).off(e,o.Draggable.END[i],this._onUp);o.DomUtil.enableImageDrag(),o.DomUtil.enableTextSelection(),this._moved&&(o.Util.cancelAnimFrame(this._animRequest),this.fire("dragend",{distance:this._newPos.distanceTo(this._startPos)})),this._moving=!1}}),o.Handler=o.Class.extend({initialize:function(t){this._map=t},enable:function(){this._enabled||(this._enabled=!0,this.addHooks())},disable:function(){this._enabled&&(this._enabled=!1,this.removeHooks())},enabled:function(){return!!this._enabled}}),o.Map.mergeOptions({dragging:!0,inertia:!o.Browser.android23,inertiaDeceleration:3400,inertiaMaxSpeed:1/0,inertiaThreshold:o.Browser.touch?32:18,easeLinearity:.25,worldCopyJump:!1}),o.Map.Drag=o.Handler.extend({addHooks:function(){if(!this._draggable){var t=this._map;this._draggable=new o.Draggable(t._mapPane,t._container),this._draggable.on({dragstart:this._onDragStart,drag:this._onDrag,dragend:this._onDragEnd},this),t.options.worldCopyJump&&(this._draggable.on("predrag",this._onPreDrag,this),t.on("viewreset",this._onViewReset,this),t.whenReady(this._onViewReset,this))}this._draggable.enable()},removeHooks:function(){this._draggable.disable()},moved:function(){return this._draggable&&this._draggable._moved},_onDragStart:function(){var t=this._map;t._panAnim&&t._panAnim.stop(),t.fire("movestart").fire("dragstart"),t.options.inertia&&(this._positions=[],this._times=[])},_onDrag:function(){if(this._map.options.inertia){var t=this._lastTime=+new Date,e=this._lastPos=this._draggable._newPos;this._positions.push(e),this._times.push(t),t-this._times[0]>200&&(this._positions.shift(),this._times.shift())}this._map.fire("move").fire("drag")},_onViewReset:function(){var t=this._map.getSize()._divideBy(2),e=this._map.latLngToLayerPoint([0,0]);this._initialWorldOffset=e.subtract(t).x,this._worldWidth=this._map.project([0,180]).x},_onPreDrag:function(){var t=this._worldWidth,e=Math.round(t/2),i=this._initialWorldOffset,n=this._draggable._newPos.x,o=(n-e+i)%t+e-i,s=(n+e+i)%t-e-i,a=Math.abs(o+i)i.inertiaThreshold||!this._positions[0];if(e.fire("dragend",t),s)e.fire("moveend");else{var a=this._lastPos.subtract(this._positions[0]),r=(this._lastTime+n-this._times[0])/1e3,h=i.easeLinearity,l=a.multiplyBy(h/r),u=l.distanceTo([0,0]),c=Math.min(i.inertiaMaxSpeed,u),d=l.multiplyBy(c/u),p=c/(i.inertiaDeceleration*h),_=d.multiplyBy(-p/2).round();_.x&&_.y?(_=e._limitOffset(_,e.options.maxBounds),o.Util.requestAnimFrame(function(){e.panBy(_,{duration:p,easeLinearity:h,noMoveStart:!0})})):e.fire("moveend")}}}),o.Map.addInitHook("addHandler","dragging",o.Map.Drag),o.Map.mergeOptions({doubleClickZoom:!0}),o.Map.DoubleClickZoom=o.Handler.extend({addHooks:function(){this._map.on("dblclick",this._onDoubleClick,this)},removeHooks:function(){this._map.off("dblclick",this._onDoubleClick,this)},_onDoubleClick:function(t){var e=this._map,i=e.getZoom()+(t.originalEvent.shiftKey?-1:1);"center"===e.options.doubleClickZoom?e.setZoom(i):e.setZoomAround(t.containerPoint,i)}}),o.Map.addInitHook("addHandler","doubleClickZoom",o.Map.DoubleClickZoom),o.Map.mergeOptions({scrollWheelZoom:!0}),o.Map.ScrollWheelZoom=o.Handler.extend({addHooks:function(){o.DomEvent.on(this._map._container,"mousewheel",this._onWheelScroll,this),o.DomEvent.on(this._map._container,"MozMousePixelScroll",o.DomEvent.preventDefault),this._delta=0},removeHooks:function(){o.DomEvent.off(this._map._container,"mousewheel",this._onWheelScroll),o.DomEvent.off(this._map._container,"MozMousePixelScroll",o.DomEvent.preventDefault)},_onWheelScroll:function(t){var e=o.DomEvent.getWheelDelta(t);this._delta+=e,this._lastMousePos=this._map.mouseEventToContainerPoint(t),this._startTime||(this._startTime=+new Date);var i=Math.max(40-(+new Date-this._startTime),0);clearTimeout(this._timer),this._timer=setTimeout(o.bind(this._performZoom,this),i),o.DomEvent.preventDefault(t),o.DomEvent.stopPropagation(t)},_performZoom:function(){var t=this._map,e=this._delta,i=t.getZoom();e=e>0?Math.ceil(e):Math.floor(e),e=Math.max(Math.min(e,4),-4),e=t._limitZoom(i+e)-i,this._delta=0,this._startTime=null,e&&("center"===t.options.scrollWheelZoom?t.setZoom(i+e):t.setZoomAround(this._lastMousePos,i+e))}}),o.Map.addInitHook("addHandler","scrollWheelZoom",o.Map.ScrollWheelZoom),o.extend(o.DomEvent,{_touchstart:o.Browser.msPointer?"MSPointerDown":o.Browser.pointer?"pointerdown":"touchstart",_touchend:o.Browser.msPointer?"MSPointerUp":o.Browser.pointer?"pointerup":"touchend",addDoubleTapListener:function(t,i,n){function s(t){var e;if(o.Browser.pointer?(_.push(t.pointerId),e=_.length):e=t.touches.length,!(e>1)){var i=Date.now(),n=i-(r||i);h=t.touches?t.touches[0]:t,l=n>0&&u>=n,r=i}}function a(t){if(o.Browser.pointer){var e=_.indexOf(t.pointerId);if(-1===e)return;_.splice(e,1)}if(l){if(o.Browser.pointer){var n,s={};for(var a in h)n=h[a],s[a]="function"==typeof n?n.bind(h):n;h=s}h.type="dblclick",i(h),r=null}}var r,h,l=!1,u=250,c="_leaflet_",d=this._touchstart,p=this._touchend,_=[];t[c+d+n]=s,t[c+p+n]=a;var m=o.Browser.pointer?e.documentElement:t;return t.addEventListener(d,s,!1),m.addEventListener(p,a,!1),o.Browser.pointer&&m.addEventListener(o.DomEvent.POINTER_CANCEL,a,!1),this},removeDoubleTapListener:function(t,i){var n="_leaflet_";return t.removeEventListener(this._touchstart,t[n+this._touchstart+i],!1),(o.Browser.pointer?e.documentElement:t).removeEventListener(this._touchend,t[n+this._touchend+i],!1),o.Browser.pointer&&e.documentElement.removeEventListener(o.DomEvent.POINTER_CANCEL,t[n+this._touchend+i],!1),this}}),o.extend(o.DomEvent,{POINTER_DOWN:o.Browser.msPointer?"MSPointerDown":"pointerdown",POINTER_MOVE:o.Browser.msPointer?"MSPointerMove":"pointermove",POINTER_UP:o.Browser.msPointer?"MSPointerUp":"pointerup",POINTER_CANCEL:o.Browser.msPointer?"MSPointerCancel":"pointercancel",_pointers:[],_pointerDocumentListener:!1,addPointerListener:function(t,e,i,n){switch(e){case"touchstart":return this.addPointerListenerStart(t,e,i,n); -case"touchend":return this.addPointerListenerEnd(t,e,i,n);case"touchmove":return this.addPointerListenerMove(t,e,i,n);default:throw"Unknown touch event type"}},addPointerListenerStart:function(t,i,n,s){var a="_leaflet_",r=this._pointers,h=function(t){o.DomEvent.preventDefault(t);for(var e=!1,i=0;i1))&&(this._moved||(o.DomUtil.addClass(e._mapPane,"leaflet-touching"),e.fire("movestart").fire("zoomstart"),this._moved=!0),o.Util.cancelAnimFrame(this._animRequest),this._animRequest=o.Util.requestAnimFrame(this._updateOnMove,this,!0,this._map._container),o.DomEvent.preventDefault(t))}},_updateOnMove:function(){var t=this._map,e=this._getScaleOrigin(),i=t.layerPointToLatLng(e),n=t.getScaleZoom(this._scale);t._animateZoom(i,n,this._startCenter,this._scale,this._delta)},_onTouchEnd:function(){if(!this._moved||!this._zooming)return this._zooming=!1,void 0;var t=this._map;this._zooming=!1,o.DomUtil.removeClass(t._mapPane,"leaflet-touching"),o.Util.cancelAnimFrame(this._animRequest),o.DomEvent.off(e,"touchmove",this._onTouchMove).off(e,"touchend",this._onTouchEnd);var i=this._getScaleOrigin(),n=t.layerPointToLatLng(i),s=t.getZoom(),a=t.getScaleZoom(this._scale)-s,r=a>0?Math.ceil(a):Math.floor(a),h=t._limitZoom(s+r),l=t.getZoomScale(h)/this._scale;t._animateZoom(n,h,i,l)},_getScaleOrigin:function(){var t=this._centerOffset.subtract(this._delta).divideBy(this._scale);return this._startCenter.add(t)}}),o.Map.addInitHook("addHandler","touchZoom",o.Map.TouchZoom),o.Map.mergeOptions({tap:!0,tapTolerance:15}),o.Map.Tap=o.Handler.extend({addHooks:function(){o.DomEvent.on(this._map._container,"touchstart",this._onDown,this)},removeHooks:function(){o.DomEvent.off(this._map._container,"touchstart",this._onDown,this)},_onDown:function(t){if(t.touches){if(o.DomEvent.preventDefault(t),this._fireClick=!0,t.touches.length>1)return this._fireClick=!1,clearTimeout(this._holdTimeout),void 0;var i=t.touches[0],n=i.target;this._startPos=this._newPos=new o.Point(i.clientX,i.clientY),n.tagName&&"a"===n.tagName.toLowerCase()&&o.DomUtil.addClass(n,"leaflet-active"),this._holdTimeout=setTimeout(o.bind(function(){this._isTapValid()&&(this._fireClick=!1,this._onUp(),this._simulateEvent("contextmenu",i))},this),1e3),o.DomEvent.on(e,"touchmove",this._onMove,this).on(e,"touchend",this._onUp,this)}},_onUp:function(t){if(clearTimeout(this._holdTimeout),o.DomEvent.off(e,"touchmove",this._onMove,this).off(e,"touchend",this._onUp,this),this._fireClick&&t&&t.changedTouches){var i=t.changedTouches[0],n=i.target;n&&n.tagName&&"a"===n.tagName.toLowerCase()&&o.DomUtil.removeClass(n,"leaflet-active"),this._isTapValid()&&this._simulateEvent("click",i)}},_isTapValid:function(){return this._newPos.distanceTo(this._startPos)<=this._map.options.tapTolerance},_onMove:function(t){var e=t.touches[0];this._newPos=new o.Point(e.clientX,e.clientY)},_simulateEvent:function(i,n){var o=e.createEvent("MouseEvents");o._simulated=!0,n.target._simulatedClick=!0,o.initMouseEvent(i,!0,!0,t,1,n.screenX,n.screenY,n.clientX,n.clientY,!1,!1,!1,!1,0,null),n.target.dispatchEvent(o)}}),o.Browser.touch&&!o.Browser.pointer&&o.Map.addInitHook("addHandler","tap",o.Map.Tap),o.Map.mergeOptions({boxZoom:!0}),o.Map.BoxZoom=o.Handler.extend({initialize:function(t){this._map=t,this._container=t._container,this._pane=t._panes.overlayPane,this._moved=!1},addHooks:function(){o.DomEvent.on(this._container,"mousedown",this._onMouseDown,this)},removeHooks:function(){o.DomEvent.off(this._container,"mousedown",this._onMouseDown),this._moved=!1},moved:function(){return this._moved},_onMouseDown:function(t){return this._moved=!1,!t.shiftKey||1!==t.which&&1!==t.button?!1:(o.DomUtil.disableTextSelection(),o.DomUtil.disableImageDrag(),this._startLayerPoint=this._map.mouseEventToLayerPoint(t),o.DomEvent.on(e,"mousemove",this._onMouseMove,this).on(e,"mouseup",this._onMouseUp,this).on(e,"keydown",this._onKeyDown,this),void 0)},_onMouseMove:function(t){this._moved||(this._box=o.DomUtil.create("div","leaflet-zoom-box",this._pane),o.DomUtil.setPosition(this._box,this._startLayerPoint),this._container.style.cursor="crosshair",this._map.fire("boxzoomstart"));var e=this._startLayerPoint,i=this._box,n=this._map.mouseEventToLayerPoint(t),s=n.subtract(e),a=new o.Point(Math.min(n.x,e.x),Math.min(n.y,e.y));o.DomUtil.setPosition(i,a),this._moved=!0,i.style.width=Math.max(0,Math.abs(s.x)-4)+"px",i.style.height=Math.max(0,Math.abs(s.y)-4)+"px"},_finish:function(){this._moved&&(this._pane.removeChild(this._box),this._container.style.cursor=""),o.DomUtil.enableTextSelection(),o.DomUtil.enableImageDrag(),o.DomEvent.off(e,"mousemove",this._onMouseMove).off(e,"mouseup",this._onMouseUp).off(e,"keydown",this._onKeyDown)},_onMouseUp:function(t){this._finish();var e=this._map,i=e.mouseEventToLayerPoint(t);if(!this._startLayerPoint.equals(i)){var n=new o.LatLngBounds(e.layerPointToLatLng(this._startLayerPoint),e.layerPointToLatLng(i));e.fitBounds(n),e.fire("boxzoomend",{boxZoomBounds:n})}},_onKeyDown:function(t){27===t.keyCode&&this._finish()}}),o.Map.addInitHook("addHandler","boxZoom",o.Map.BoxZoom),o.Map.mergeOptions({keyboard:!0,keyboardPanOffset:80,keyboardZoomOffset:1}),o.Map.Keyboard=o.Handler.extend({keyCodes:{left:[37],right:[39],down:[40],up:[38],zoomIn:[187,107,61,171],zoomOut:[189,109,173]},initialize:function(t){this._map=t,this._setPanOffset(t.options.keyboardPanOffset),this._setZoomOffset(t.options.keyboardZoomOffset)},addHooks:function(){var t=this._map._container;-1===t.tabIndex&&(t.tabIndex="0"),o.DomEvent.on(t,"focus",this._onFocus,this).on(t,"blur",this._onBlur,this).on(t,"mousedown",this._onMouseDown,this),this._map.on("focus",this._addHooks,this).on("blur",this._removeHooks,this)},removeHooks:function(){this._removeHooks();var t=this._map._container;o.DomEvent.off(t,"focus",this._onFocus,this).off(t,"blur",this._onBlur,this).off(t,"mousedown",this._onMouseDown,this),this._map.off("focus",this._addHooks,this).off("blur",this._removeHooks,this)},_onMouseDown:function(){if(!this._focused){var i=e.body,n=e.documentElement,o=i.scrollTop||n.scrollTop,s=i.scrollLeft||n.scrollLeft;this._map._container.focus(),t.scrollTo(s,o)}},_onFocus:function(){this._focused=!0,this._map.fire("focus")},_onBlur:function(){this._focused=!1,this._map.fire("blur")},_setPanOffset:function(t){var e,i,n=this._panKeys={},o=this.keyCodes;for(e=0,i=o.left.length;i>e;e++)n[o.left[e]]=[-1*t,0];for(e=0,i=o.right.length;i>e;e++)n[o.right[e]]=[t,0];for(e=0,i=o.down.length;i>e;e++)n[o.down[e]]=[0,t];for(e=0,i=o.up.length;i>e;e++)n[o.up[e]]=[0,-1*t]},_setZoomOffset:function(t){var e,i,n=this._zoomKeys={},o=this.keyCodes;for(e=0,i=o.zoomIn.length;i>e;e++)n[o.zoomIn[e]]=t;for(e=0,i=o.zoomOut.length;i>e;e++)n[o.zoomOut[e]]=-t},_addHooks:function(){o.DomEvent.on(e,"keydown",this._onKeyDown,this)},_removeHooks:function(){o.DomEvent.off(e,"keydown",this._onKeyDown,this)},_onKeyDown:function(t){var e=t.keyCode,i=this._map;if(e in this._panKeys){if(i._panAnim&&i._panAnim._inProgress)return;i.panBy(this._panKeys[e]),i.options.maxBounds&&i.panInsideBounds(i.options.maxBounds)}else{if(!(e in this._zoomKeys))return;i.setZoom(i.getZoom()+this._zoomKeys[e])}o.DomEvent.stop(t)}}),o.Map.addInitHook("addHandler","keyboard",o.Map.Keyboard),o.Handler.MarkerDrag=o.Handler.extend({initialize:function(t){this._marker=t},addHooks:function(){var t=this._marker._icon;this._draggable||(this._draggable=new o.Draggable(t,t)),this._draggable.on("dragstart",this._onDragStart,this).on("drag",this._onDrag,this).on("dragend",this._onDragEnd,this),this._draggable.enable(),o.DomUtil.addClass(this._marker._icon,"leaflet-marker-draggable")},removeHooks:function(){this._draggable.off("dragstart",this._onDragStart,this).off("drag",this._onDrag,this).off("dragend",this._onDragEnd,this),this._draggable.disable(),o.DomUtil.removeClass(this._marker._icon,"leaflet-marker-draggable")},moved:function(){return this._draggable&&this._draggable._moved},_onDragStart:function(){this._marker.closePopup().fire("movestart").fire("dragstart")},_onDrag:function(){var t=this._marker,e=t._shadow,i=o.DomUtil.getPosition(t._icon),n=t._map.layerPointToLatLng(i);e&&o.DomUtil.setPosition(e,i),t._latlng=n,t.fire("move",{latlng:n}).fire("drag")},_onDragEnd:function(t){this._marker.fire("moveend").fire("dragend",t)}}),o.Control=o.Class.extend({options:{position:"topright"},initialize:function(t){o.setOptions(this,t)},getPosition:function(){return this.options.position},setPosition:function(t){var e=this._map;return e&&e.removeControl(this),this.options.position=t,e&&e.addControl(this),this},getContainer:function(){return this._container},addTo:function(t){this._map=t;var e=this._container=this.onAdd(t),i=this.getPosition(),n=t._controlCorners[i];return o.DomUtil.addClass(e,"leaflet-control"),-1!==i.indexOf("bottom")?n.insertBefore(e,n.firstChild):n.appendChild(e),this},removeFrom:function(t){var e=this.getPosition(),i=t._controlCorners[e];return i.removeChild(this._container),this._map=null,this.onRemove&&this.onRemove(t),this},_refocusOnMap:function(){this._map&&this._map.getContainer().focus()}}),o.control=function(t){return new o.Control(t)},o.Map.include({addControl:function(t){return t.addTo(this),this},removeControl:function(t){return t.removeFrom(this),this},_initControlPos:function(){function t(t,s){var a=i+t+" "+i+s;e[t+s]=o.DomUtil.create("div",a,n)}var e=this._controlCorners={},i="leaflet-",n=this._controlContainer=o.DomUtil.create("div",i+"control-container",this._container);t("top","left"),t("top","right"),t("bottom","left"),t("bottom","right")},_clearControlPos:function(){this._container.removeChild(this._controlContainer)}}),o.Control.Zoom=o.Control.extend({options:{position:"topleft",zoomInText:"+",zoomInTitle:"Zoom in",zoomOutText:"-",zoomOutTitle:"Zoom out"},onAdd:function(t){var e="leaflet-control-zoom",i=o.DomUtil.create("div",e+" leaflet-bar");return this._map=t,this._zoomInButton=this._createButton(this.options.zoomInText,this.options.zoomInTitle,e+"-in",i,this._zoomIn,this),this._zoomOutButton=this._createButton(this.options.zoomOutText,this.options.zoomOutTitle,e+"-out",i,this._zoomOut,this),this._updateDisabled(),t.on("zoomend zoomlevelschange",this._updateDisabled,this),i},onRemove:function(t){t.off("zoomend zoomlevelschange",this._updateDisabled,this)},_zoomIn:function(t){this._map.zoomIn(t.shiftKey?3:1)},_zoomOut:function(t){this._map.zoomOut(t.shiftKey?3:1)},_createButton:function(t,e,i,n,s,a){var r=o.DomUtil.create("a",i,n);r.innerHTML=t,r.href="#",r.title=e;var h=o.DomEvent.stopPropagation;return o.DomEvent.on(r,"click",h).on(r,"mousedown",h).on(r,"dblclick",h).on(r,"click",o.DomEvent.preventDefault).on(r,"click",s,a).on(r,"click",this._refocusOnMap,a),r},_updateDisabled:function(){var t=this._map,e="leaflet-disabled";o.DomUtil.removeClass(this._zoomInButton,e),o.DomUtil.removeClass(this._zoomOutButton,e),t._zoom===t.getMinZoom()&&o.DomUtil.addClass(this._zoomOutButton,e),t._zoom===t.getMaxZoom()&&o.DomUtil.addClass(this._zoomInButton,e)}}),o.Map.mergeOptions({zoomControl:!0}),o.Map.addInitHook(function(){this.options.zoomControl&&(this.zoomControl=new o.Control.Zoom,this.addControl(this.zoomControl))}),o.control.zoom=function(t){return new o.Control.Zoom(t)},o.Control.Attribution=o.Control.extend({options:{position:"bottomright",prefix:'
Leaflet'},initialize:function(t){o.setOptions(this,t),this._attributions={}},onAdd:function(t){this._container=o.DomUtil.create("div","leaflet-control-attribution"),o.DomEvent.disableClickPropagation(this._container);for(var e in t._layers)t._layers[e].getAttribution&&this.addAttribution(t._layers[e].getAttribution());return t.on("layeradd",this._onLayerAdd,this).on("layerremove",this._onLayerRemove,this),this._update(),this._container},onRemove:function(t){t.off("layeradd",this._onLayerAdd).off("layerremove",this._onLayerRemove)},setPrefix:function(t){return this.options.prefix=t,this._update(),this},addAttribution:function(t){return t?(this._attributions[t]||(this._attributions[t]=0),this._attributions[t]++,this._update(),this):void 0},removeAttribution:function(t){return t?(this._attributions[t]&&(this._attributions[t]--,this._update()),this):void 0},_update:function(){if(this._map){var t=[];for(var e in this._attributions)this._attributions[e]&&t.push(e);var i=[];this.options.prefix&&i.push(this.options.prefix),t.length&&i.push(t.join(", ")),this._container.innerHTML=i.join(" | ")}},_onLayerAdd:function(t){t.layer.getAttribution&&this.addAttribution(t.layer.getAttribution())},_onLayerRemove:function(t){t.layer.getAttribution&&this.removeAttribution(t.layer.getAttribution())}}),o.Map.mergeOptions({attributionControl:!0}),o.Map.addInitHook(function(){this.options.attributionControl&&(this.attributionControl=(new o.Control.Attribution).addTo(this))}),o.control.attribution=function(t){return new o.Control.Attribution(t)},o.Control.Scale=o.Control.extend({options:{position:"bottomleft",maxWidth:100,metric:!0,imperial:!0,updateWhenIdle:!1},onAdd:function(t){this._map=t;var e="leaflet-control-scale",i=o.DomUtil.create("div",e),n=this.options;return this._addScales(n,e,i),t.on(n.updateWhenIdle?"moveend":"move",this._update,this),t.whenReady(this._update,this),i},onRemove:function(t){t.off(this.options.updateWhenIdle?"moveend":"move",this._update,this)},_addScales:function(t,e,i){t.metric&&(this._mScale=o.DomUtil.create("div",e+"-line",i)),t.imperial&&(this._iScale=o.DomUtil.create("div",e+"-line",i))},_update:function(){var t=this._map.getBounds(),e=t.getCenter().lat,i=6378137*Math.PI*Math.cos(e*Math.PI/180),n=i*(t.getNorthEast().lng-t.getSouthWest().lng)/180,o=this._map.getSize(),s=this.options,a=0;o.x>0&&(a=n*(s.maxWidth/o.x)),this._updateScales(s,a)},_updateScales:function(t,e){t.metric&&e&&this._updateMetric(e),t.imperial&&e&&this._updateImperial(e)},_updateMetric:function(t){var e=this._getRoundNum(t);this._mScale.style.width=this._getScaleWidth(e/t)+"px",this._mScale.innerHTML=1e3>e?e+" m":e/1e3+" km"},_updateImperial:function(t){var e,i,n,o=3.2808399*t,s=this._iScale;o>5280?(e=o/5280,i=this._getRoundNum(e),s.style.width=this._getScaleWidth(i/e)+"px",s.innerHTML=i+" mi"):(n=this._getRoundNum(o),s.style.width=this._getScaleWidth(n/o)+"px",s.innerHTML=n+" ft")},_getScaleWidth:function(t){return Math.round(this.options.maxWidth*t)-10},_getRoundNum:function(t){var e=Math.pow(10,(Math.floor(t)+"").length-1),i=t/e;return i=i>=10?10:i>=5?5:i>=3?3:i>=2?2:1,e*i}}),o.control.scale=function(t){return new o.Control.Scale(t)},o.Control.Layers=o.Control.extend({options:{collapsed:!0,position:"topright",autoZIndex:!0},initialize:function(t,e,i){o.setOptions(this,i),this._layers={},this._lastZIndex=0,this._handlingClick=!1;for(var n in t)this._addLayer(t[n],n);for(n in e)this._addLayer(e[n],n,!0)},onAdd:function(t){return this._initLayout(),this._update(),t.on("layeradd",this._onLayerChange,this).on("layerremove",this._onLayerChange,this),this._container},onRemove:function(t){t.off("layeradd",this._onLayerChange).off("layerremove",this._onLayerChange)},addBaseLayer:function(t,e){return this._addLayer(t,e),this._update(),this},addOverlay:function(t,e){return this._addLayer(t,e,!0),this._update(),this},removeLayer:function(t){var e=o.stamp(t);return delete this._layers[e],this._update(),this},_initLayout:function(){var t="leaflet-control-layers",e=this._container=o.DomUtil.create("div",t);e.setAttribute("aria-haspopup",!0),o.Browser.touch?o.DomEvent.on(e,"click",o.DomEvent.stopPropagation):o.DomEvent.disableClickPropagation(e).disableScrollPropagation(e);var i=this._form=o.DomUtil.create("form",t+"-list");if(this.options.collapsed){o.Browser.android||o.DomEvent.on(e,"mouseover",this._expand,this).on(e,"mouseout",this._collapse,this);var n=this._layersLink=o.DomUtil.create("a",t+"-toggle",e);n.href="#",n.title="Layers",o.Browser.touch?o.DomEvent.on(n,"click",o.DomEvent.stop).on(n,"click",this._expand,this):o.DomEvent.on(n,"focus",this._expand,this),o.DomEvent.on(i,"click",function(){setTimeout(o.bind(this._onInputClick,this),0)},this),this._map.on("click",this._collapse,this)}else this._expand();this._baseLayersList=o.DomUtil.create("div",t+"-base",i),this._separator=o.DomUtil.create("div",t+"-separator",i),this._overlaysList=o.DomUtil.create("div",t+"-overlays",i),e.appendChild(i)},_addLayer:function(t,e,i){var n=o.stamp(t);this._layers[n]={layer:t,name:e,overlay:i},this.options.autoZIndex&&t.setZIndex&&(this._lastZIndex++,t.setZIndex(this._lastZIndex))},_update:function(){if(this._container){this._baseLayersList.innerHTML="",this._overlaysList.innerHTML="";var t,e,i=!1,n=!1;for(t in this._layers)e=this._layers[t],this._addItem(e),n=n||e.overlay,i=i||!e.overlay;this._separator.style.display=n&&i?"":"none"}},_onLayerChange:function(t){var e=this._layers[o.stamp(t.layer)];if(e){this._handlingClick||this._update();var i=e.overlay?"layeradd"===t.type?"overlayadd":"overlayremove":"layeradd"===t.type?"baselayerchange":null;i&&this._map.fire(i,e)}},_createRadioElement:function(t,i){var n='t;t++)e=n[t],i=this._layers[e.layerId],e.checked&&!this._map.hasLayer(i.layer)?this._map.addLayer(i.layer):!e.checked&&this._map.hasLayer(i.layer)&&this._map.removeLayer(i.layer);this._handlingClick=!1,this._refocusOnMap()},_expand:function(){o.DomUtil.addClass(this._container,"leaflet-control-layers-expanded")},_collapse:function(){this._container.className=this._container.className.replace(" leaflet-control-layers-expanded","")}}),o.control.layers=function(t,e,i){return new o.Control.Layers(t,e,i)},o.PosAnimation=o.Class.extend({includes:o.Mixin.Events,run:function(t,e,i,n){this.stop(),this._el=t,this._inProgress=!0,this._newPos=e,this.fire("start"),t.style[o.DomUtil.TRANSITION]="all "+(i||.25)+"s cubic-bezier(0,0,"+(n||.5)+",1)",o.DomEvent.on(t,o.DomUtil.TRANSITION_END,this._onTransitionEnd,this),o.DomUtil.setPosition(t,e),o.Util.falseFn(t.offsetWidth),this._stepTimer=setInterval(o.bind(this._onStep,this),50)},stop:function(){this._inProgress&&(o.DomUtil.setPosition(this._el,this._getPos()),this._onTransitionEnd(),o.Util.falseFn(this._el.offsetWidth))},_onStep:function(){var t=this._getPos();return t?(this._el._leaflet_pos=t,this.fire("step"),void 0):(this._onTransitionEnd(),void 0)},_transformRe:/([-+]?(?:\d*\.)?\d+)\D*, ([-+]?(?:\d*\.)?\d+)\D*\)/,_getPos:function(){var e,i,n,s=this._el,a=t.getComputedStyle(s);if(o.Browser.any3d){if(n=a[o.DomUtil.TRANSFORM].match(this._transformRe),!n)return;e=parseFloat(n[1]),i=parseFloat(n[2])}else e=parseFloat(a.left),i=parseFloat(a.top);return new o.Point(e,i,!0)},_onTransitionEnd:function(){o.DomEvent.off(this._el,o.DomUtil.TRANSITION_END,this._onTransitionEnd,this),this._inProgress&&(this._inProgress=!1,this._el.style[o.DomUtil.TRANSITION]="",this._el._leaflet_pos=this._newPos,clearInterval(this._stepTimer),this.fire("step").fire("end"))}}),o.Map.include({setView:function(t,e,n){if(e=e===i?this._zoom:this._limitZoom(e),t=this._limitCenter(o.latLng(t),e,this.options.maxBounds),n=n||{},this._panAnim&&this._panAnim.stop(),this._loaded&&!n.reset&&n!==!0){n.animate!==i&&(n.zoom=o.extend({animate:n.animate},n.zoom),n.pan=o.extend({animate:n.animate},n.pan));var s=this._zoom!==e?this._tryAnimatedZoom&&this._tryAnimatedZoom(t,e,n.zoom):this._tryAnimatedPan(t,n.pan);if(s)return clearTimeout(this._sizeTimer),this}return this._resetView(t,e),this},panBy:function(t,e){if(t=o.point(t).round(),e=e||{},!t.x&&!t.y)return this;if(this._panAnim||(this._panAnim=new o.PosAnimation,this._panAnim.on({step:this._onPanTransitionStep,end:this._onPanTransitionEnd},this)),e.noMoveStart||this.fire("movestart"),e.animate!==!1){o.DomUtil.addClass(this._mapPane,"leaflet-pan-anim");var i=this._getMapPanePos().subtract(t);this._panAnim.run(this._mapPane,i,e.duration||.25,e.easeLinearity)}else this._rawPanBy(t),this.fire("move").fire("moveend");return this},_onPanTransitionStep:function(){this.fire("move")},_onPanTransitionEnd:function(){o.DomUtil.removeClass(this._mapPane,"leaflet-pan-anim"),this.fire("moveend")},_tryAnimatedPan:function(t,e){var i=this._getCenterOffset(t)._floor();return(e&&e.animate)===!0||this.getSize().contains(i)?(this.panBy(i,e),!0):!1}}),o.PosAnimation=o.DomUtil.TRANSITION?o.PosAnimation:o.PosAnimation.extend({run:function(t,e,i,n){this.stop(),this._el=t,this._inProgress=!0,this._duration=i||.25,this._easeOutPower=1/Math.max(n||.5,.2),this._startPos=o.DomUtil.getPosition(t),this._offset=e.subtract(this._startPos),this._startTime=+new Date,this.fire("start"),this._animate()},stop:function(){this._inProgress&&(this._step(),this._complete())},_animate:function(){this._animId=o.Util.requestAnimFrame(this._animate,this),this._step()},_step:function(){var t=+new Date-this._startTime,e=1e3*this._duration;e>t?this._runFrame(this._easeOut(t/e)):(this._runFrame(1),this._complete())},_runFrame:function(t){var e=this._startPos.add(this._offset.multiplyBy(t));o.DomUtil.setPosition(this._el,e),this.fire("step")},_complete:function(){o.Util.cancelAnimFrame(this._animId),this._inProgress=!1,this.fire("end")},_easeOut:function(t){return 1-Math.pow(1-t,this._easeOutPower)}}),o.Map.mergeOptions({zoomAnimation:!0,zoomAnimationThreshold:4}),o.DomUtil.TRANSITION&&o.Map.addInitHook(function(){this._zoomAnimated=this.options.zoomAnimation&&o.DomUtil.TRANSITION&&o.Browser.any3d&&!o.Browser.android23&&!o.Browser.mobileOpera,this._zoomAnimated&&o.DomEvent.on(this._mapPane,o.DomUtil.TRANSITION_END,this._catchTransitionEnd,this)}),o.Map.include(o.DomUtil.TRANSITION?{_catchTransitionEnd:function(){this._animatingZoom&&this._onZoomTransitionEnd()},_nothingToAnimate:function(){return!this._container.getElementsByClassName("leaflet-zoom-animated").length},_tryAnimatedZoom:function(t,e,i){if(this._animatingZoom)return!0;if(i=i||{},!this._zoomAnimated||i.animate===!1||this._nothingToAnimate()||Math.abs(e-this._zoom)>this.options.zoomAnimationThreshold)return!1;var n=this.getZoomScale(e),o=this._getCenterOffset(t)._divideBy(1-1/n),s=this._getCenterLayerPoint()._add(o);return i.animate===!0||this.getSize().contains(o)?(this.fire("movestart").fire("zoomstart"),this._animateZoom(t,e,s,n,null,!0),!0):!1},_animateZoom:function(t,e,i,n,s,a){this._animatingZoom=!0,o.DomUtil.addClass(this._mapPane,"leaflet-zoom-anim"),this._animateToCenter=t,this._animateToZoom=e,o.Draggable&&(o.Draggable._disabled=!0),this.fire("zoomanim",{center:t,zoom:e,origin:i,scale:n,delta:s,backwards:a})},_onZoomTransitionEnd:function(){this._animatingZoom=!1,o.DomUtil.removeClass(this._mapPane,"leaflet-zoom-anim"),this._resetView(this._animateToCenter,this._animateToZoom,!0,!0),o.Draggable&&(o.Draggable._disabled=!1)}}:{}),o.TileLayer.include({_animateZoom:function(t){this._animating||(this._animating=!0,this._prepareBgBuffer());var e=this._bgBuffer,i=o.DomUtil.TRANSFORM,n=t.delta?o.DomUtil.getTranslateString(t.delta):e.style[i],s=o.DomUtil.getScaleString(t.scale,t.origin);e.style[i]=t.backwards?s+" "+n:n+" "+s},_endZoomAnim:function(){var t=this._tileContainer,e=this._bgBuffer;t.style.visibility="",t.parentNode.appendChild(t),o.Util.falseFn(e.offsetWidth),this._animating=!1},_clearBgBuffer:function(){var t=this._map;!t||t._animatingZoom||t.touchZoom._zooming||(this._bgBuffer.innerHTML="",this._bgBuffer.style[o.DomUtil.TRANSFORM]="")},_prepareBgBuffer:function(){var t=this._tileContainer,e=this._bgBuffer,i=this._getLoadedTilesPercentage(e),n=this._getLoadedTilesPercentage(t);return e&&i>.5&&.5>n?(t.style.visibility="hidden",this._stopLoadingImages(t),void 0):(e.style.visibility="hidden",e.style[o.DomUtil.TRANSFORM]="",this._tileContainer=e,e=this._bgBuffer=t,this._stopLoadingImages(e),clearTimeout(this._clearBgBufferTimer),void 0)},_getLoadedTilesPercentage:function(t){var e,i,n=t.getElementsByTagName("img"),o=0;for(e=0,i=n.length;i>e;e++)n[e].complete&&o++;return o/i},_stopLoadingImages:function(t){var e,i,n,s=Array.prototype.slice.call(t.getElementsByTagName("img"));for(e=0,i=s.length;i>e;e++)n=s[e],n.complete||(n.onload=o.Util.falseFn,n.onerror=o.Util.falseFn,n.src=o.Util.emptyImageUrl,n.parentNode.removeChild(n))}}),o.Map.include({_defaultLocateOptions:{watch:!1,setView:!1,maxZoom:1/0,timeout:1e4,maximumAge:0,enableHighAccuracy:!1},locate:function(t){if(t=this._locateOptions=o.extend(this._defaultLocateOptions,t),!navigator.geolocation)return this._handleGeolocationError({code:0,message:"Geolocation not supported."}),this;var e=o.bind(this._handleGeolocationResponse,this),i=o.bind(this._handleGeolocationError,this);return t.watch?this._locationWatchId=navigator.geolocation.watchPosition(e,i,t):navigator.geolocation.getCurrentPosition(e,i,t),this},stopLocate:function(){return navigator.geolocation&&navigator.geolocation.clearWatch(this._locationWatchId),this._locateOptions&&(this._locateOptions.setView=!1),this},_handleGeolocationError:function(t){var e=t.code,i=t.message||(1===e?"permission denied":2===e?"position unavailable":"timeout");this._locateOptions.setView&&!this._loaded&&this.fitWorld(),this.fire("locationerror",{code:e,message:"Geolocation error: "+i+"."})},_handleGeolocationResponse:function(t){var e=t.coords.latitude,i=t.coords.longitude,n=new o.LatLng(e,i),s=180*t.coords.accuracy/40075017,a=s/Math.cos(o.LatLng.DEG_TO_RAD*e),r=o.latLngBounds([e-s,i-a],[e+s,i+a]),h=this._locateOptions;if(h.setView){var l=Math.min(this.getBoundsZoom(r),h.maxZoom);this.setView(n,l)}var u={latlng:n,bounds:r,timestamp:t.timestamp};for(var c in t.coords)"number"==typeof t.coords[c]&&(u[c]=t.coords[c]);this.fire("locationfound",u)}})}(window,document); \ No newline at end of file +!function(t,e,i){var n=t.L,o={};o.version="0.7.1","object"==typeof module&&"object"==typeof module.exports?module.exports=o:"function"==typeof define&&define.amd&&define(o),o.noConflict=function(){return t.L=n,this},t.L=o,o.Util={extend:function(t){var e,i,n,o,s=Array.prototype.slice.call(arguments,1);for(i=0,n=s.length;n>i;i++){o=s[i]||{};for(e in o)o.hasOwnProperty(e)&&(t[e]=o[e])}return t},bind:function(t,e){var i=arguments.length>2?Array.prototype.slice.call(arguments,2):null;return function(){return t.apply(e,i||arguments)}},stamp:function(){var t=0,e="_leaflet_id";return function(i){return i[e]=i[e]||++t,i[e]}}(),invokeEach:function(t,e,i){var n,o;if("object"==typeof t){o=Array.prototype.slice.call(arguments,3);for(n in t)e.apply(i,[n,t[n]].concat(o));return!0}return!1},limitExecByInterval:function(t,e,i){var n,o;return function s(){var a=arguments;return n?(o=!0,void 0):(n=!0,setTimeout(function(){n=!1,o&&(s.apply(i,a),o=!1)},e),t.apply(i,a),void 0)}},falseFn:function(){return!1},formatNum:function(t,e){var i=Math.pow(10,e||5);return Math.round(t*i)/i},trim:function(t){return t.trim?t.trim():t.replace(/^\s+|\s+$/g,"")},splitWords:function(t){return o.Util.trim(t).split(/\s+/)},setOptions:function(t,e){return t.options=o.extend({},t.options,e),t.options},getParamString:function(t,e,i){var n=[];for(var o in t)n.push(encodeURIComponent(i?o.toUpperCase():o)+"="+encodeURIComponent(t[o]));return(e&&-1!==e.indexOf("?")?"&":"?")+n.join("&")},template:function(t,e){return t.replace(/\{ *([\w_]+) *\}/g,function(t,n){var o=e[n];if(o===i)throw new Error("No value provided for variable "+t);return"function"==typeof o&&(o=o(e)),o})},isArray:Array.isArray||function(t){return"[object Array]"===Object.prototype.toString.call(t)},emptyImageUrl:"data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs="},function(){function e(e){var i,n,o=["webkit","moz","o","ms"];for(i=0;it;t++)n._initHooks[t].call(this)}},e},o.Class.include=function(t){o.extend(this.prototype,t)},o.Class.mergeOptions=function(t){o.extend(this.prototype.options,t)},o.Class.addInitHook=function(t){var e=Array.prototype.slice.call(arguments,1),i="function"==typeof t?t:function(){this[t].apply(this,e)};this.prototype._initHooks=this.prototype._initHooks||[],this.prototype._initHooks.push(i)};var s="_leaflet_events";o.Mixin={},o.Mixin.Events={addEventListener:function(t,e,i){if(o.Util.invokeEach(t,this.addEventListener,this,e,i))return this;var n,a,r,h,l,u,c,d=this[s]=this[s]||{},p=i&&i!==this&&o.stamp(i);for(t=o.Util.splitWords(t),n=0,a=t.length;a>n;n++)r={action:e,context:i||this},h=t[n],p?(l=h+"_idx",u=l+"_len",c=d[l]=d[l]||{},c[p]||(c[p]=[],d[u]=(d[u]||0)+1),c[p].push(r)):(d[h]=d[h]||[],d[h].push(r));return this},hasEventListeners:function(t){var e=this[s];return!!e&&(t in e&&e[t].length>0||t+"_idx"in e&&e[t+"_idx_len"]>0)},removeEventListener:function(t,e,i){if(!this[s])return this;if(!t)return this.clearAllEventListeners();if(o.Util.invokeEach(t,this.removeEventListener,this,e,i))return this;var n,a,r,h,l,u,c,d,p,_=this[s],m=i&&i!==this&&o.stamp(i);for(t=o.Util.splitWords(t),n=0,a=t.length;a>n;n++)if(r=t[n],u=r+"_idx",c=u+"_len",d=_[u],e){if(h=m&&d?d[m]:_[r]){for(l=h.length-1;l>=0;l--)h[l].action!==e||i&&h[l].context!==i||(p=h.splice(l,1),p[0].action=o.Util.falseFn);i&&d&&0===h.length&&(delete d[m],_[c]--)}}else delete _[r],delete _[u],delete _[c];return this},clearAllEventListeners:function(){return delete this[s],this},fireEvent:function(t,e){if(!this.hasEventListeners(t))return this;var i,n,a,r,h,l=o.Util.extend({},e,{type:t,target:this}),u=this[s];if(u[t])for(i=u[t].slice(),n=0,a=i.length;a>n;n++)i[n].action.call(i[n].context,l);r=u[t+"_idx"];for(h in r)if(i=r[h].slice())for(n=0,a=i.length;a>n;n++)i[n].action.call(i[n].context,l);return this},addOneTimeEventListener:function(t,e,i){if(o.Util.invokeEach(t,this.addOneTimeEventListener,this,e,i))return this;var n=o.bind(function(){this.removeEventListener(t,e,i).removeEventListener(t,n,i)},this);return this.addEventListener(t,e,i).addEventListener(t,n,i)}},o.Mixin.Events.on=o.Mixin.Events.addEventListener,o.Mixin.Events.off=o.Mixin.Events.removeEventListener,o.Mixin.Events.once=o.Mixin.Events.addOneTimeEventListener,o.Mixin.Events.fire=o.Mixin.Events.fireEvent,function(){var n="ActiveXObject"in t,s=n&&!e.addEventListener,a=navigator.userAgent.toLowerCase(),r=-1!==a.indexOf("webkit"),h=-1!==a.indexOf("chrome"),l=-1!==a.indexOf("phantom"),u=-1!==a.indexOf("android"),c=-1!==a.search("android [23]"),d=-1!==a.indexOf("gecko"),p=typeof orientation!=i+"",_=t.navigator&&t.navigator.msPointerEnabled&&t.navigator.msMaxTouchPoints&&!t.PointerEvent,m=t.PointerEvent&&t.navigator.pointerEnabled&&t.navigator.maxTouchPoints||_,f="devicePixelRatio"in t&&t.devicePixelRatio>1||"matchMedia"in t&&t.matchMedia("(min-resolution:144dpi)")&&t.matchMedia("(min-resolution:144dpi)").matches,g=e.documentElement,v=n&&"transition"in g.style,y="WebKitCSSMatrix"in t&&"m11"in new t.WebKitCSSMatrix&&!c,P="MozPerspective"in g.style,L="OTransition"in g.style,x=!t.L_DISABLE_3D&&(v||y||P||L)&&!l,w=!t.L_NO_TOUCH&&!l&&function(){var t="ontouchstart";if(m||t in g)return!0;var i=e.createElement("div"),n=!1;return i.setAttribute?(i.setAttribute(t,"return;"),"function"==typeof i[t]&&(n=!0),i.removeAttribute(t),i=null,n):!1}();o.Browser={ie:n,ielt9:s,webkit:r,gecko:d&&!r&&!t.opera&&!n,android:u,android23:c,chrome:h,ie3d:v,webkit3d:y,gecko3d:P,opera3d:L,any3d:x,mobile:p,mobileWebkit:p&&r,mobileWebkit3d:p&&y,mobileOpera:p&&t.opera,touch:w,msPointer:_,pointer:m,retina:f}}(),o.Point=function(t,e,i){this.x=i?Math.round(t):t,this.y=i?Math.round(e):e},o.Point.prototype={clone:function(){return new o.Point(this.x,this.y)},add:function(t){return this.clone()._add(o.point(t))},_add:function(t){return this.x+=t.x,this.y+=t.y,this},subtract:function(t){return this.clone()._subtract(o.point(t))},_subtract:function(t){return this.x-=t.x,this.y-=t.y,this},divideBy:function(t){return this.clone()._divideBy(t)},_divideBy:function(t){return this.x/=t,this.y/=t,this},multiplyBy:function(t){return this.clone()._multiplyBy(t)},_multiplyBy:function(t){return this.x*=t,this.y*=t,this},round:function(){return this.clone()._round()},_round:function(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this},floor:function(){return this.clone()._floor()},_floor:function(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this},distanceTo:function(t){t=o.point(t);var e=t.x-this.x,i=t.y-this.y;return Math.sqrt(e*e+i*i)},equals:function(t){return t=o.point(t),t.x===this.x&&t.y===this.y},contains:function(t){return t=o.point(t),Math.abs(t.x)<=Math.abs(this.x)&&Math.abs(t.y)<=Math.abs(this.y)},toString:function(){return"Point("+o.Util.formatNum(this.x)+", "+o.Util.formatNum(this.y)+")"}},o.point=function(t,e,n){return t instanceof o.Point?t:o.Util.isArray(t)?new o.Point(t[0],t[1]):t===i||null===t?t:new o.Point(t,e,n)},o.Bounds=function(t,e){if(t)for(var i=e?[t,e]:t,n=0,o=i.length;o>n;n++)this.extend(i[n])},o.Bounds.prototype={extend:function(t){return t=o.point(t),this.min||this.max?(this.min.x=Math.min(t.x,this.min.x),this.max.x=Math.max(t.x,this.max.x),this.min.y=Math.min(t.y,this.min.y),this.max.y=Math.max(t.y,this.max.y)):(this.min=t.clone(),this.max=t.clone()),this},getCenter:function(t){return new o.Point((this.min.x+this.max.x)/2,(this.min.y+this.max.y)/2,t)},getBottomLeft:function(){return new o.Point(this.min.x,this.max.y)},getTopRight:function(){return new o.Point(this.max.x,this.min.y)},getSize:function(){return this.max.subtract(this.min)},contains:function(t){var e,i;return t="number"==typeof t[0]||t instanceof o.Point?o.point(t):o.bounds(t),t instanceof o.Bounds?(e=t.min,i=t.max):e=i=t,e.x>=this.min.x&&i.x<=this.max.x&&e.y>=this.min.y&&i.y<=this.max.y},intersects:function(t){t=o.bounds(t);var e=this.min,i=this.max,n=t.min,s=t.max,a=s.x>=e.x&&n.x<=i.x,r=s.y>=e.y&&n.y<=i.y;return a&&r},isValid:function(){return!(!this.min||!this.max)}},o.bounds=function(t,e){return!t||t instanceof o.Bounds?t:new o.Bounds(t,e)},o.Transformation=function(t,e,i,n){this._a=t,this._b=e,this._c=i,this._d=n},o.Transformation.prototype={transform:function(t,e){return this._transform(t.clone(),e)},_transform:function(t,e){return e=e||1,t.x=e*(this._a*t.x+this._b),t.y=e*(this._c*t.y+this._d),t},untransform:function(t,e){return e=e||1,new o.Point((t.x/e-this._b)/this._a,(t.y/e-this._d)/this._c)}},o.DomUtil={get:function(t){return"string"==typeof t?e.getElementById(t):t},getStyle:function(t,i){var n=t.style[i];if(!n&&t.currentStyle&&(n=t.currentStyle[i]),(!n||"auto"===n)&&e.defaultView){var o=e.defaultView.getComputedStyle(t,null);n=o?o[i]:null}return"auto"===n?null:n},getViewportOffset:function(t){var i,n=0,s=0,a=t,r=e.body,h=e.documentElement;do{if(n+=a.offsetTop||0,s+=a.offsetLeft||0,n+=parseInt(o.DomUtil.getStyle(a,"borderTopWidth"),10)||0,s+=parseInt(o.DomUtil.getStyle(a,"borderLeftWidth"),10)||0,i=o.DomUtil.getStyle(a,"position"),a.offsetParent===r&&"absolute"===i)break;if("fixed"===i){n+=r.scrollTop||h.scrollTop||0,s+=r.scrollLeft||h.scrollLeft||0;break}if("relative"===i&&!a.offsetLeft){var l=o.DomUtil.getStyle(a,"width"),u=o.DomUtil.getStyle(a,"max-width"),c=a.getBoundingClientRect();("none"!==l||"none"!==u)&&(s+=c.left+a.clientLeft),n+=c.top+(r.scrollTop||h.scrollTop||0);break}a=a.offsetParent}while(a);a=t;do{if(a===r)break;n-=a.scrollTop||0,s-=a.scrollLeft||0,a=a.parentNode}while(a);return new o.Point(s,n)},documentIsLtr:function(){return o.DomUtil._docIsLtrCached||(o.DomUtil._docIsLtrCached=!0,o.DomUtil._docIsLtr="ltr"===o.DomUtil.getStyle(e.body,"direction")),o.DomUtil._docIsLtr},create:function(t,i,n){var o=e.createElement(t);return o.className=i,n&&n.appendChild(o),o},hasClass:function(t,e){if(t.classList!==i)return t.classList.contains(e);var n=o.DomUtil._getClass(t);return n.length>0&&new RegExp("(^|\\s)"+e+"(\\s|$)").test(n)},addClass:function(t,e){if(t.classList!==i)for(var n=o.Util.splitWords(e),s=0,a=n.length;a>s;s++)t.classList.add(n[s]);else if(!o.DomUtil.hasClass(t,e)){var r=o.DomUtil._getClass(t);o.DomUtil._setClass(t,(r?r+" ":"")+e)}},removeClass:function(t,e){t.classList!==i?t.classList.remove(e):o.DomUtil._setClass(t,o.Util.trim((" "+o.DomUtil._getClass(t)+" ").replace(" "+e+" "," ")))},_setClass:function(t,e){t.className.baseVal===i?t.className=e:t.className.baseVal=e},_getClass:function(t){return t.className.baseVal===i?t.className:t.className.baseVal},setOpacity:function(t,e){if("opacity"in t.style)t.style.opacity=e;else if("filter"in t.style){var i=!1,n="DXImageTransform.Microsoft.Alpha";try{i=t.filters.item(n)}catch(o){if(1===e)return}e=Math.round(100*e),i?(i.Enabled=100!==e,i.Opacity=e):t.style.filter+=" progid:"+n+"(opacity="+e+")"}},testProp:function(t){for(var i=e.documentElement.style,n=0;ni||i===e?e:t),new o.LatLng(this.lat,i)}},o.latLng=function(t,e){return t instanceof o.LatLng?t:o.Util.isArray(t)?"number"==typeof t[0]||"string"==typeof t[0]?new o.LatLng(t[0],t[1],t[2]):null:t===i||null===t?t:"object"==typeof t&&"lat"in t?new o.LatLng(t.lat,"lng"in t?t.lng:t.lon):e===i?null:new o.LatLng(t,e)},o.LatLngBounds=function(t,e){if(t)for(var i=e?[t,e]:t,n=0,o=i.length;o>n;n++)this.extend(i[n])},o.LatLngBounds.prototype={extend:function(t){if(!t)return this;var e=o.latLng(t);return t=null!==e?e:o.latLngBounds(t),t instanceof o.LatLng?this._southWest||this._northEast?(this._southWest.lat=Math.min(t.lat,this._southWest.lat),this._southWest.lng=Math.min(t.lng,this._southWest.lng),this._northEast.lat=Math.max(t.lat,this._northEast.lat),this._northEast.lng=Math.max(t.lng,this._northEast.lng)):(this._southWest=new o.LatLng(t.lat,t.lng),this._northEast=new o.LatLng(t.lat,t.lng)):t instanceof o.LatLngBounds&&(this.extend(t._southWest),this.extend(t._northEast)),this},pad:function(t){var e=this._southWest,i=this._northEast,n=Math.abs(e.lat-i.lat)*t,s=Math.abs(e.lng-i.lng)*t;return new o.LatLngBounds(new o.LatLng(e.lat-n,e.lng-s),new o.LatLng(i.lat+n,i.lng+s))},getCenter:function(){return new o.LatLng((this._southWest.lat+this._northEast.lat)/2,(this._southWest.lng+this._northEast.lng)/2)},getSouthWest:function(){return this._southWest},getNorthEast:function(){return this._northEast},getNorthWest:function(){return new o.LatLng(this.getNorth(),this.getWest())},getSouthEast:function(){return new o.LatLng(this.getSouth(),this.getEast())},getWest:function(){return this._southWest.lng},getSouth:function(){return this._southWest.lat},getEast:function(){return this._northEast.lng},getNorth:function(){return this._northEast.lat},contains:function(t){t="number"==typeof t[0]||t instanceof o.LatLng?o.latLng(t):o.latLngBounds(t);var e,i,n=this._southWest,s=this._northEast;return t instanceof o.LatLngBounds?(e=t.getSouthWest(),i=t.getNorthEast()):e=i=t,e.lat>=n.lat&&i.lat<=s.lat&&e.lng>=n.lng&&i.lng<=s.lng},intersects:function(t){t=o.latLngBounds(t);var e=this._southWest,i=this._northEast,n=t.getSouthWest(),s=t.getNorthEast(),a=s.lat>=e.lat&&n.lat<=i.lat,r=s.lng>=e.lng&&n.lng<=i.lng;return a&&r},toBBoxString:function(){return[this.getWest(),this.getSouth(),this.getEast(),this.getNorth()].join(",")},equals:function(t){return t?(t=o.latLngBounds(t),this._southWest.equals(t.getSouthWest())&&this._northEast.equals(t.getNorthEast())):!1},isValid:function(){return!(!this._southWest||!this._northEast)}},o.latLngBounds=function(t,e){return!t||t instanceof o.LatLngBounds?t:new o.LatLngBounds(t,e)},o.Projection={},o.Projection.SphericalMercator={MAX_LATITUDE:85.0511287798,project:function(t){var e=o.LatLng.DEG_TO_RAD,i=this.MAX_LATITUDE,n=Math.max(Math.min(i,t.lat),-i),s=t.lng*e,a=n*e;return a=Math.log(Math.tan(Math.PI/4+a/2)),new o.Point(s,a)},unproject:function(t){var e=o.LatLng.RAD_TO_DEG,i=t.x*e,n=(2*Math.atan(Math.exp(t.y))-Math.PI/2)*e;return new o.LatLng(n,i)}},o.Projection.LonLat={project:function(t){return new o.Point(t.lng,t.lat)},unproject:function(t){return new o.LatLng(t.y,t.x)}},o.CRS={latLngToPoint:function(t,e){var i=this.projection.project(t),n=this.scale(e);return this.transformation._transform(i,n)},pointToLatLng:function(t,e){var i=this.scale(e),n=this.transformation.untransform(t,i);return this.projection.unproject(n)},project:function(t){return this.projection.project(t)},scale:function(t){return 256*Math.pow(2,t)},getSize:function(t){var e=this.scale(t);return o.point(e,e)}},o.CRS.Simple=o.extend({},o.CRS,{projection:o.Projection.LonLat,transformation:new o.Transformation(1,0,-1,0),scale:function(t){return Math.pow(2,t)}}),o.CRS.EPSG3857=o.extend({},o.CRS,{code:"EPSG:3857",projection:o.Projection.SphericalMercator,transformation:new o.Transformation(.5/Math.PI,.5,-.5/Math.PI,.5),project:function(t){var e=this.projection.project(t),i=6378137;return e.multiplyBy(i)}}),o.CRS.EPSG900913=o.extend({},o.CRS.EPSG3857,{code:"EPSG:900913"}),o.CRS.EPSG4326=o.extend({},o.CRS,{code:"EPSG:4326",projection:o.Projection.LonLat,transformation:new o.Transformation(1/360,.5,-1/360,.5)}),o.Map=o.Class.extend({includes:o.Mixin.Events,options:{crs:o.CRS.EPSG3857,fadeAnimation:o.DomUtil.TRANSITION&&!o.Browser.android23,trackResize:!0,markerZoomAnimation:o.DomUtil.TRANSITION&&o.Browser.any3d},initialize:function(t,e){e=o.setOptions(this,e),this._initContainer(t),this._initLayout(),this._onResize=o.bind(this._onResize,this),this._initEvents(),e.maxBounds&&this.setMaxBounds(e.maxBounds),e.center&&e.zoom!==i&&this.setView(o.latLng(e.center),e.zoom,{reset:!0}),this._handlers=[],this._layers={},this._zoomBoundLayers={},this._tileLayersNum=0,this.callInitHooks(),this._addLayers(e.layers)},setView:function(t,e){return e=e===i?this.getZoom():e,this._resetView(o.latLng(t),this._limitZoom(e)),this},setZoom:function(t,e){return this._loaded?this.setView(this.getCenter(),t,{zoom:e}):(this._zoom=this._limitZoom(t),this)},zoomIn:function(t,e){return this.setZoom(this._zoom+(t||1),e)},zoomOut:function(t,e){return this.setZoom(this._zoom-(t||1),e)},setZoomAround:function(t,e,i){var n=this.getZoomScale(e),s=this.getSize().divideBy(2),a=t instanceof o.Point?t:this.latLngToContainerPoint(t),r=a.subtract(s).multiplyBy(1-1/n),h=this.containerPointToLatLng(s.add(r));return this.setView(h,e,{zoom:i})},fitBounds:function(t,e){e=e||{},t=t.getBounds?t.getBounds():o.latLngBounds(t);var i=o.point(e.paddingTopLeft||e.padding||[0,0]),n=o.point(e.paddingBottomRight||e.padding||[0,0]),s=this.getBoundsZoom(t,!1,i.add(n)),a=n.subtract(i).divideBy(2),r=this.project(t.getSouthWest(),s),h=this.project(t.getNorthEast(),s),l=this.unproject(r.add(h).divideBy(2).add(a),s);return s=e&&e.maxZoom?Math.min(e.maxZoom,s):s,this.setView(l,s,e)},fitWorld:function(t){return this.fitBounds([[-90,-180],[90,180]],t)},panTo:function(t,e){return this.setView(t,this._zoom,{pan:e})},panBy:function(t){return this.fire("movestart"),this._rawPanBy(o.point(t)),this.fire("move"),this.fire("moveend")},setMaxBounds:function(t){return t=o.latLngBounds(t),this.options.maxBounds=t,t?(this._loaded&&this._panInsideMaxBounds(),this.on("moveend",this._panInsideMaxBounds,this)):this.off("moveend",this._panInsideMaxBounds,this)},panInsideBounds:function(t,e){var i=this.getCenter(),n=this._limitCenter(i,this._zoom,t);return i.equals(n)?this:this.panTo(n,e)},addLayer:function(t){var e=o.stamp(t);return this._layers[e]?this:(this._layers[e]=t,!t.options||isNaN(t.options.maxZoom)&&isNaN(t.options.minZoom)||(this._zoomBoundLayers[e]=t,this._updateZoomLevels()),this.options.zoomAnimation&&o.TileLayer&&t instanceof o.TileLayer&&(this._tileLayersNum++,this._tileLayersToLoad++,t.on("load",this._onTileLayerLoad,this)),this._loaded&&this._layerAdd(t),this)},removeLayer:function(t){var e=o.stamp(t);return this._layers[e]?(this._loaded&&t.onRemove(this),delete this._layers[e],this._loaded&&this.fire("layerremove",{layer:t}),this._zoomBoundLayers[e]&&(delete this._zoomBoundLayers[e],this._updateZoomLevels()),this.options.zoomAnimation&&o.TileLayer&&t instanceof o.TileLayer&&(this._tileLayersNum--,this._tileLayersToLoad--,t.off("load",this._onTileLayerLoad,this)),this):this},hasLayer:function(t){return t?o.stamp(t)in this._layers:!1},eachLayer:function(t,e){for(var i in this._layers)t.call(e,this._layers[i]);return this},invalidateSize:function(t){if(!this._loaded)return this;t=o.extend({animate:!1,pan:!0},t===!0?{animate:!0}:t);var e=this.getSize();this._sizeChanged=!0,this._initialCenter=null;var i=this.getSize(),n=e.divideBy(2).round(),s=i.divideBy(2).round(),a=n.subtract(s);return a.x||a.y?(t.animate&&t.pan?this.panBy(a):(t.pan&&this._rawPanBy(a),this.fire("move"),t.debounceMoveend?(clearTimeout(this._sizeTimer),this._sizeTimer=setTimeout(o.bind(this.fire,this,"moveend"),200)):this.fire("moveend")),this.fire("resize",{oldSize:e,newSize:i})):this},addHandler:function(t,e){if(!e)return this;var i=this[t]=new e(this);return this._handlers.push(i),this.options[t]&&i.enable(),this},remove:function(){this._loaded&&this.fire("unload"),this._initEvents("off");try{delete this._container._leaflet}catch(t){this._container._leaflet=i}return this._clearPanes(),this._clearControlPos&&this._clearControlPos(),this._clearHandlers(),this},getCenter:function(){return this._checkIfLoaded(),this._initialCenter&&!this._moved()?this._initialCenter:this.layerPointToLatLng(this._getCenterLayerPoint())},getZoom:function(){return this._zoom},getBounds:function(){var t=this.getPixelBounds(),e=this.unproject(t.getBottomLeft()),i=this.unproject(t.getTopRight());return new o.LatLngBounds(e,i)},getMinZoom:function(){return this.options.minZoom===i?this._layersMinZoom===i?0:this._layersMinZoom:this.options.minZoom},getMaxZoom:function(){return this.options.maxZoom===i?this._layersMaxZoom===i?1/0:this._layersMaxZoom:this.options.maxZoom},getBoundsZoom:function(t,e,i){t=o.latLngBounds(t);var n,s=this.getMinZoom()-(e?1:0),a=this.getMaxZoom(),r=this.getSize(),h=t.getNorthWest(),l=t.getSouthEast(),u=!0;i=o.point(i||[0,0]);do s++,n=this.project(l,s).subtract(this.project(h,s)).add(i),u=e?n.x=s);return u&&e?null:e?s:s-1},getSize:function(){return(!this._size||this._sizeChanged)&&(this._size=new o.Point(this._container.clientWidth,this._container.clientHeight),this._sizeChanged=!1),this._size.clone()},getPixelBounds:function(){var t=this._getTopLeftPoint();return new o.Bounds(t,t.add(this.getSize()))},getPixelOrigin:function(){return this._checkIfLoaded(),this._initialTopLeftPoint},getPanes:function(){return this._panes},getContainer:function(){return this._container},getZoomScale:function(t){var e=this.options.crs;return e.scale(t)/e.scale(this._zoom)},getScaleZoom:function(t){return this._zoom+Math.log(t)/Math.LN2},project:function(t,e){return e=e===i?this._zoom:e,this.options.crs.latLngToPoint(o.latLng(t),e)},unproject:function(t,e){return e=e===i?this._zoom:e,this.options.crs.pointToLatLng(o.point(t),e)},layerPointToLatLng:function(t){var e=o.point(t).add(this.getPixelOrigin());return this.unproject(e)},latLngToLayerPoint:function(t){var e=this.project(o.latLng(t))._round();return e._subtract(this.getPixelOrigin())},containerPointToLayerPoint:function(t){return o.point(t).subtract(this._getMapPanePos())},layerPointToContainerPoint:function(t){return o.point(t).add(this._getMapPanePos())},containerPointToLatLng:function(t){var e=this.containerPointToLayerPoint(o.point(t));return this.layerPointToLatLng(e)},latLngToContainerPoint:function(t){return this.layerPointToContainerPoint(this.latLngToLayerPoint(o.latLng(t)))},mouseEventToContainerPoint:function(t){return o.DomEvent.getMousePosition(t,this._container)},mouseEventToLayerPoint:function(t){return this.containerPointToLayerPoint(this.mouseEventToContainerPoint(t))},mouseEventToLatLng:function(t){return this.layerPointToLatLng(this.mouseEventToLayerPoint(t))},_initContainer:function(t){var e=this._container=o.DomUtil.get(t);if(!e)throw new Error("Map container not found.");if(e._leaflet)throw new Error("Map container is already initialized.");e._leaflet=!0},_initLayout:function(){var t=this._container;o.DomUtil.addClass(t,"leaflet-container"+(o.Browser.touch?" leaflet-touch":"")+(o.Browser.retina?" leaflet-retina":"")+(o.Browser.ielt9?" leaflet-oldie":"")+(this.options.fadeAnimation?" leaflet-fade-anim":""));var e=o.DomUtil.getStyle(t,"position");"absolute"!==e&&"relative"!==e&&"fixed"!==e&&(t.style.position="relative"),this._initPanes(),this._initControlPos&&this._initControlPos()},_initPanes:function(){var t=this._panes={};this._mapPane=t.mapPane=this._createPane("leaflet-map-pane",this._container),this._tilePane=t.tilePane=this._createPane("leaflet-tile-pane",this._mapPane),t.objectsPane=this._createPane("leaflet-objects-pane",this._mapPane),t.shadowPane=this._createPane("leaflet-shadow-pane"),t.overlayPane=this._createPane("leaflet-overlay-pane"),t.markerPane=this._createPane("leaflet-marker-pane"),t.popupPane=this._createPane("leaflet-popup-pane");var e=" leaflet-zoom-hide";this.options.markerZoomAnimation||(o.DomUtil.addClass(t.markerPane,e),o.DomUtil.addClass(t.shadowPane,e),o.DomUtil.addClass(t.popupPane,e))},_createPane:function(t,e){return o.DomUtil.create("div",t,e||this._panes.objectsPane)},_clearPanes:function(){this._container.removeChild(this._mapPane)},_addLayers:function(t){t=t?o.Util.isArray(t)?t:[t]:[];for(var e=0,i=t.length;i>e;e++)this.addLayer(t[e])},_resetView:function(t,e,i,n){var s=this._zoom!==e;n||(this.fire("movestart"),s&&this.fire("zoomstart")),this._zoom=e,this._initialCenter=t,this._initialTopLeftPoint=this._getNewTopLeftPoint(t),i?this._initialTopLeftPoint._add(this._getMapPanePos()):o.DomUtil.setPosition(this._mapPane,new o.Point(0,0)),this._tileLayersToLoad=this._tileLayersNum;var a=!this._loaded;this._loaded=!0,a&&(this.fire("load"),this.eachLayer(this._layerAdd,this)),this.fire("viewreset",{hard:!i}),this.fire("move"),(s||n)&&this.fire("zoomend"),this.fire("moveend",{hard:!i})},_rawPanBy:function(t){o.DomUtil.setPosition(this._mapPane,this._getMapPanePos().subtract(t))},_getZoomSpan:function(){return this.getMaxZoom()-this.getMinZoom()},_updateZoomLevels:function(){var t,e=1/0,n=-1/0,o=this._getZoomSpan();for(t in this._zoomBoundLayers){var s=this._zoomBoundLayers[t];isNaN(s.options.minZoom)||(e=Math.min(e,s.options.minZoom)),isNaN(s.options.maxZoom)||(n=Math.max(n,s.options.maxZoom))}t===i?this._layersMaxZoom=this._layersMinZoom=i:(this._layersMaxZoom=n,this._layersMinZoom=e),o!==this._getZoomSpan()&&this.fire("zoomlevelschange")},_panInsideMaxBounds:function(){this.panInsideBounds(this.options.maxBounds)},_checkIfLoaded:function(){if(!this._loaded)throw new Error("Set map center and zoom first.")},_initEvents:function(e){if(o.DomEvent){e=e||"on",o.DomEvent[e](this._container,"click",this._onMouseClick,this);var i,n,s=["dblclick","mousedown","mouseup","mouseenter","mouseleave","mousemove","contextmenu"];for(i=0,n=s.length;n>i;i++)o.DomEvent[e](this._container,s[i],this._fireMouseEvent,this);this.options.trackResize&&o.DomEvent[e](t,"resize",this._onResize,this)}},_onResize:function(){o.Util.cancelAnimFrame(this._resizeRequest),this._resizeRequest=o.Util.requestAnimFrame(function(){this.invalidateSize({debounceMoveend:!0})},this,!1,this._container)},_onMouseClick:function(t){!this._loaded||!t._simulated&&(this.dragging&&this.dragging.moved()||this.boxZoom&&this.boxZoom.moved())||o.DomEvent._skipped(t)||(this.fire("preclick"),this._fireMouseEvent(t))},_fireMouseEvent:function(t){if(this._loaded&&!o.DomEvent._skipped(t)){var e=t.type;if(e="mouseenter"===e?"mouseover":"mouseleave"===e?"mouseout":e,this.hasEventListeners(e)){"contextmenu"===e&&o.DomEvent.preventDefault(t);var i=this.mouseEventToContainerPoint(t),n=this.containerPointToLayerPoint(i),s=this.layerPointToLatLng(n);this.fire(e,{latlng:s,layerPoint:n,containerPoint:i,originalEvent:t})}}},_onTileLayerLoad:function(){this._tileLayersToLoad--,this._tileLayersNum&&!this._tileLayersToLoad&&this.fire("tilelayersload")},_clearHandlers:function(){for(var t=0,e=this._handlers.length;e>t;t++)this._handlers[t].disable()},whenReady:function(t,e){return this._loaded?t.call(e||this,this):this.on("load",t,e),this},_layerAdd:function(t){t.onAdd(this),this.fire("layeradd",{layer:t})},_getMapPanePos:function(){return o.DomUtil.getPosition(this._mapPane)},_moved:function(){var t=this._getMapPanePos();return t&&!t.equals([0,0])},_getTopLeftPoint:function(){return this.getPixelOrigin().subtract(this._getMapPanePos())},_getNewTopLeftPoint:function(t,e){var i=this.getSize()._divideBy(2);return this.project(t,e)._subtract(i)._round()},_latLngToNewLayerPoint:function(t,e,i){var n=this._getNewTopLeftPoint(i,e).add(this._getMapPanePos());return this.project(t,e)._subtract(n)},_getCenterLayerPoint:function(){return this.containerPointToLayerPoint(this.getSize()._divideBy(2))},_getCenterOffset:function(t){return this.latLngToLayerPoint(t).subtract(this._getCenterLayerPoint())},_limitCenter:function(t,e,i){if(!i)return t;var n=this.project(t,e),s=this.getSize().divideBy(2),a=new o.Bounds(n.subtract(s),n.add(s)),r=this._getBoundsOffset(a,i,e);return this.unproject(n.add(r),e)},_limitOffset:function(t,e){if(!e)return t;var i=this.getPixelBounds(),n=new o.Bounds(i.min.add(t),i.max.add(t));return t.add(this._getBoundsOffset(n,e))},_getBoundsOffset:function(t,e,i){var n=this.project(e.getNorthWest(),i).subtract(t.min),s=this.project(e.getSouthEast(),i).subtract(t.max),a=this._rebound(n.x,-s.x),r=this._rebound(n.y,-s.y);return new o.Point(a,r)},_rebound:function(t,e){return t+e>0?Math.round(t-e)/2:Math.max(0,Math.ceil(t))-Math.max(0,Math.floor(e))},_limitZoom:function(t){var e=this.getMinZoom(),i=this.getMaxZoom();return Math.max(e,Math.min(i,t))}}),o.map=function(t,e){return new o.Map(t,e)},o.Projection.Mercator={MAX_LATITUDE:85.0840591556,R_MINOR:6356752.314245179,R_MAJOR:6378137,project:function(t){var e=o.LatLng.DEG_TO_RAD,i=this.MAX_LATITUDE,n=Math.max(Math.min(i,t.lat),-i),s=this.R_MAJOR,a=this.R_MINOR,r=t.lng*e*s,h=n*e,l=a/s,u=Math.sqrt(1-l*l),c=u*Math.sin(h);c=Math.pow((1-c)/(1+c),.5*u);var d=Math.tan(.5*(.5*Math.PI-h))/c;return h=-s*Math.log(d),new o.Point(r,h)},unproject:function(t){for(var e,i=o.LatLng.RAD_TO_DEG,n=this.R_MAJOR,s=this.R_MINOR,a=t.x*i/n,r=s/n,h=Math.sqrt(1-r*r),l=Math.exp(-t.y/n),u=Math.PI/2-2*Math.atan(l),c=15,d=1e-7,p=c,_=.1;Math.abs(_)>d&&--p>0;)e=h*Math.sin(u),_=Math.PI/2-2*Math.atan(l*Math.pow((1-e)/(1+e),.5*h))-u,u+=_; +return new o.LatLng(u*i,a)}},o.CRS.EPSG3395=o.extend({},o.CRS,{code:"EPSG:3395",projection:o.Projection.Mercator,transformation:function(){var t=o.Projection.Mercator,e=t.R_MAJOR,i=.5/(Math.PI*e);return new o.Transformation(i,.5,-i,.5)}()}),o.TileLayer=o.Class.extend({includes:o.Mixin.Events,options:{minZoom:0,maxZoom:18,tileSize:256,subdomains:"abc",errorTileUrl:"",attribution:"",zoomOffset:0,opacity:1,unloadInvisibleTiles:o.Browser.mobile,updateWhenIdle:o.Browser.mobile},initialize:function(t,e){e=o.setOptions(this,e),e.detectRetina&&o.Browser.retina&&e.maxZoom>0&&(e.tileSize=Math.floor(e.tileSize/2),e.zoomOffset++,e.minZoom>0&&e.minZoom--,this.options.maxZoom--),e.bounds&&(e.bounds=o.latLngBounds(e.bounds)),this._url=t;var i=this.options.subdomains;"string"==typeof i&&(this.options.subdomains=i.split(""))},onAdd:function(t){this._map=t,this._animated=t._zoomAnimated,this._initContainer(),t.on({viewreset:this._reset,moveend:this._update},this),this._animated&&t.on({zoomanim:this._animateZoom,zoomend:this._endZoomAnim},this),this.options.updateWhenIdle||(this._limitedUpdate=o.Util.limitExecByInterval(this._update,150,this),t.on("move",this._limitedUpdate,this)),this._reset(),this._update()},addTo:function(t){return t.addLayer(this),this},onRemove:function(t){this._container.parentNode.removeChild(this._container),t.off({viewreset:this._reset,moveend:this._update},this),this._animated&&t.off({zoomanim:this._animateZoom,zoomend:this._endZoomAnim},this),this.options.updateWhenIdle||t.off("move",this._limitedUpdate,this),this._container=null,this._map=null},bringToFront:function(){var t=this._map._panes.tilePane;return this._container&&(t.appendChild(this._container),this._setAutoZIndex(t,Math.max)),this},bringToBack:function(){var t=this._map._panes.tilePane;return this._container&&(t.insertBefore(this._container,t.firstChild),this._setAutoZIndex(t,Math.min)),this},getAttribution:function(){return this.options.attribution},getContainer:function(){return this._container},setOpacity:function(t){return this.options.opacity=t,this._map&&this._updateOpacity(),this},setZIndex:function(t){return this.options.zIndex=t,this._updateZIndex(),this},setUrl:function(t,e){return this._url=t,e||this.redraw(),this},redraw:function(){return this._map&&(this._reset({hard:!0}),this._update()),this},_updateZIndex:function(){this._container&&this.options.zIndex!==i&&(this._container.style.zIndex=this.options.zIndex)},_setAutoZIndex:function(t,e){var i,n,o,s=t.children,a=-e(1/0,-1/0);for(n=0,o=s.length;o>n;n++)s[n]!==this._container&&(i=parseInt(s[n].style.zIndex,10),isNaN(i)||(a=e(a,i)));this.options.zIndex=this._container.style.zIndex=(isFinite(a)?a:0)+e(1,-1)},_updateOpacity:function(){var t,e=this._tiles;if(o.Browser.ielt9)for(t in e)o.DomUtil.setOpacity(e[t],this.options.opacity);else o.DomUtil.setOpacity(this._container,this.options.opacity)},_initContainer:function(){var t=this._map._panes.tilePane;if(!this._container){if(this._container=o.DomUtil.create("div","leaflet-layer"),this._updateZIndex(),this._animated){var e="leaflet-tile-container";this._bgBuffer=o.DomUtil.create("div",e,this._container),this._tileContainer=o.DomUtil.create("div",e,this._container)}else this._tileContainer=this._container;t.appendChild(this._container),this.options.opacity<1&&this._updateOpacity()}},_reset:function(t){for(var e in this._tiles)this.fire("tileunload",{tile:this._tiles[e]});this._tiles={},this._tilesToLoad=0,this.options.reuseTiles&&(this._unusedTiles=[]),this._tileContainer.innerHTML="",this._animated&&t&&t.hard&&this._clearBgBuffer(),this._initContainer()},_getTileSize:function(){var t=this._map,e=t.getZoom()+this.options.zoomOffset,i=this.options.maxNativeZoom,n=this.options.tileSize;return i&&e>i&&(n=Math.round(t.getZoomScale(e)/t.getZoomScale(i)*n)),n},_update:function(){if(this._map){var t=this._map,e=t.getPixelBounds(),i=t.getZoom(),n=this._getTileSize();if(!(i>this.options.maxZoom||in;n++)this._addTile(a[n],l);this._tileContainer.appendChild(l)}},_tileShouldBeLoaded:function(t){if(t.x+":"+t.y in this._tiles)return!1;var e=this.options;if(!e.continuousWorld){var i=this._getWrapTileNum();if(e.noWrap&&(t.x<0||t.x>=i.x)||t.y<0||t.y>=i.y)return!1}if(e.bounds){var n=e.tileSize,o=t.multiplyBy(n),s=o.add([n,n]),a=this._map.unproject(o),r=this._map.unproject(s);if(e.continuousWorld||e.noWrap||(a=a.wrap(),r=r.wrap()),!e.bounds.intersects([a,r]))return!1}return!0},_removeOtherTiles:function(t){var e,i,n,o;for(o in this._tiles)e=o.split(":"),i=parseInt(e[0],10),n=parseInt(e[1],10),(it.max.x||nt.max.y)&&this._removeTile(o)},_removeTile:function(t){var e=this._tiles[t];this.fire("tileunload",{tile:e,url:e.src}),this.options.reuseTiles?(o.DomUtil.removeClass(e,"leaflet-tile-loaded"),this._unusedTiles.push(e)):e.parentNode===this._tileContainer&&this._tileContainer.removeChild(e),o.Browser.android||(e.onload=null,e.src=o.Util.emptyImageUrl),delete this._tiles[t]},_addTile:function(t,e){var i=this._getTilePos(t),n=this._getTile();o.DomUtil.setPosition(n,i,o.Browser.chrome),this._tiles[t.x+":"+t.y]=n,this._loadTile(n,t),n.parentNode!==this._tileContainer&&e.appendChild(n)},_getZoomForUrl:function(){var t=this.options,e=this._map.getZoom();return t.zoomReverse&&(e=t.maxZoom-e),e+=t.zoomOffset,t.maxNativeZoom?Math.min(e,t.maxNativeZoom):e},_getTilePos:function(t){var e=this._map.getPixelOrigin(),i=this._getTileSize();return t.multiplyBy(i).subtract(e)},getTileUrl:function(t){return o.Util.template(this._url,o.extend({s:this._getSubdomain(t),z:t.z,x:t.x,y:t.y},this.options))},_getWrapTileNum:function(){var t=this._map.options.crs,e=t.getSize(this._map.getZoom());return e.divideBy(this.options.tileSize)},_adjustTilePoint:function(t){var e=this._getWrapTileNum();this.options.continuousWorld||this.options.noWrap||(t.x=(t.x%e.x+e.x)%e.x),this.options.tms&&(t.y=e.y-t.y-1),t.z=this._getZoomForUrl()},_getSubdomain:function(t){var e=Math.abs(t.x+t.y)%this.options.subdomains.length;return this.options.subdomains[e]},_getTile:function(){if(this.options.reuseTiles&&this._unusedTiles.length>0){var t=this._unusedTiles.pop();return this._resetTile(t),t}return this._createTile()},_resetTile:function(){},_createTile:function(){var t=o.DomUtil.create("img","leaflet-tile");return t.style.width=t.style.height=this._getTileSize()+"px",t.galleryimg="no",t.onselectstart=t.onmousemove=o.Util.falseFn,o.Browser.ielt9&&this.options.opacity!==i&&o.DomUtil.setOpacity(t,this.options.opacity),o.Browser.mobileWebkit3d&&(t.style.WebkitBackfaceVisibility="hidden"),t},_loadTile:function(t,e){t._layer=this,t.onload=this._tileOnLoad,t.onerror=this._tileOnError,this._adjustTilePoint(e),t.src=this.getTileUrl(e),this.fire("tileloadstart",{tile:t,url:t.src})},_tileLoaded:function(){this._tilesToLoad--,this._animated&&o.DomUtil.addClass(this._tileContainer,"leaflet-zoom-animated"),this._tilesToLoad||(this.fire("load"),this._animated&&(clearTimeout(this._clearBgBufferTimer),this._clearBgBufferTimer=setTimeout(o.bind(this._clearBgBuffer,this),500)))},_tileOnLoad:function(){var t=this._layer;this.src!==o.Util.emptyImageUrl&&(o.DomUtil.addClass(this,"leaflet-tile-loaded"),t.fire("tileload",{tile:this,url:this.src})),t._tileLoaded()},_tileOnError:function(){var t=this._layer;t.fire("tileerror",{tile:this,url:this.src});var e=t.options.errorTileUrl;e&&(this.src=e),t._tileLoaded()}}),o.tileLayer=function(t,e){return new o.TileLayer(t,e)},o.TileLayer.WMS=o.TileLayer.extend({defaultWmsParams:{service:"WMS",request:"GetMap",version:"1.1.1",layers:"",styles:"",format:"image/jpeg",transparent:!1},initialize:function(t,e){this._url=t;var i=o.extend({},this.defaultWmsParams),n=e.tileSize||this.options.tileSize;i.width=i.height=e.detectRetina&&o.Browser.retina?2*n:n;for(var s in e)this.options.hasOwnProperty(s)||"crs"===s||(i[s]=e[s]);this.wmsParams=i,o.setOptions(this,e)},onAdd:function(t){this._crs=this.options.crs||t.options.crs,this._wmsVersion=parseFloat(this.wmsParams.version);var e=this._wmsVersion>=1.3?"crs":"srs";this.wmsParams[e]=this._crs.code,o.TileLayer.prototype.onAdd.call(this,t)},getTileUrl:function(t){var e=this._map,i=this.options.tileSize,n=t.multiplyBy(i),s=n.add([i,i]),a=this._crs.project(e.unproject(n,t.z)),r=this._crs.project(e.unproject(s,t.z)),h=this._wmsVersion>=1.3&&this._crs===o.CRS.EPSG4326?[r.y,a.x,a.y,r.x].join(","):[a.x,r.y,r.x,a.y].join(","),l=o.Util.template(this._url,{s:this._getSubdomain(t)});return l+o.Util.getParamString(this.wmsParams,l,!0)+"&BBOX="+h},setParams:function(t,e){return o.extend(this.wmsParams,t),e||this.redraw(),this}}),o.tileLayer.wms=function(t,e){return new o.TileLayer.WMS(t,e)},o.TileLayer.Canvas=o.TileLayer.extend({options:{async:!1},initialize:function(t){o.setOptions(this,t)},redraw:function(){this._map&&(this._reset({hard:!0}),this._update());for(var t in this._tiles)this._redrawTile(this._tiles[t]);return this},_redrawTile:function(t){this.drawTile(t,t._tilePoint,this._map._zoom)},_createTile:function(){var t=o.DomUtil.create("canvas","leaflet-tile");return t.width=t.height=this.options.tileSize,t.onselectstart=t.onmousemove=o.Util.falseFn,t},_loadTile:function(t,e){t._layer=this,t._tilePoint=e,this._redrawTile(t),this.options.async||this.tileDrawn(t)},drawTile:function(){},tileDrawn:function(t){this._tileOnLoad.call(t)}}),o.tileLayer.canvas=function(t){return new o.TileLayer.Canvas(t)},o.ImageOverlay=o.Class.extend({includes:o.Mixin.Events,options:{opacity:1},initialize:function(t,e,i){this._url=t,this._bounds=o.latLngBounds(e),o.setOptions(this,i)},onAdd:function(t){this._map=t,this._image||this._initImage(),t._panes.overlayPane.appendChild(this._image),t.on("viewreset",this._reset,this),t.options.zoomAnimation&&o.Browser.any3d&&t.on("zoomanim",this._animateZoom,this),this._reset()},onRemove:function(t){t.getPanes().overlayPane.removeChild(this._image),t.off("viewreset",this._reset,this),t.options.zoomAnimation&&t.off("zoomanim",this._animateZoom,this)},addTo:function(t){return t.addLayer(this),this},setOpacity:function(t){return this.options.opacity=t,this._updateOpacity(),this},bringToFront:function(){return this._image&&this._map._panes.overlayPane.appendChild(this._image),this},bringToBack:function(){var t=this._map._panes.overlayPane;return this._image&&t.insertBefore(this._image,t.firstChild),this},setUrl:function(t){this._url=t,this._image.src=this._url},getAttribution:function(){return this.options.attribution},_initImage:function(){this._image=o.DomUtil.create("img","leaflet-image-layer"),this._map.options.zoomAnimation&&o.Browser.any3d?o.DomUtil.addClass(this._image,"leaflet-zoom-animated"):o.DomUtil.addClass(this._image,"leaflet-zoom-hide"),this._updateOpacity(),o.extend(this._image,{galleryimg:"no",onselectstart:o.Util.falseFn,onmousemove:o.Util.falseFn,onload:o.bind(this._onImageLoad,this),src:this._url})},_animateZoom:function(t){var e=this._map,i=this._image,n=e.getZoomScale(t.zoom),s=this._bounds.getNorthWest(),a=this._bounds.getSouthEast(),r=e._latLngToNewLayerPoint(s,t.zoom,t.center),h=e._latLngToNewLayerPoint(a,t.zoom,t.center)._subtract(r),l=r._add(h._multiplyBy(.5*(1-1/n)));i.style[o.DomUtil.TRANSFORM]=o.DomUtil.getTranslateString(l)+" scale("+n+") "},_reset:function(){var t=this._image,e=this._map.latLngToLayerPoint(this._bounds.getNorthWest()),i=this._map.latLngToLayerPoint(this._bounds.getSouthEast())._subtract(e);o.DomUtil.setPosition(t,e),t.style.width=i.x+"px",t.style.height=i.y+"px"},_onImageLoad:function(){this.fire("load")},_updateOpacity:function(){o.DomUtil.setOpacity(this._image,this.options.opacity)}}),o.imageOverlay=function(t,e,i){return new o.ImageOverlay(t,e,i)},o.Icon=o.Class.extend({options:{className:""},initialize:function(t){o.setOptions(this,t)},createIcon:function(t){return this._createIcon("icon",t)},createShadow:function(t){return this._createIcon("shadow",t)},_createIcon:function(t,e){var i=this._getIconUrl(t);if(!i){if("icon"===t)throw new Error("iconUrl not set in Icon options (see the docs).");return null}var n;return n=e&&"IMG"===e.tagName?this._createImg(i,e):this._createImg(i),this._setIconStyles(n,t),n},_setIconStyles:function(t,e){var i,n=this.options,s=o.point(n[e+"Size"]);i="shadow"===e?o.point(n.shadowAnchor||n.iconAnchor):o.point(n.iconAnchor),!i&&s&&(i=s.divideBy(2,!0)),t.className="leaflet-marker-"+e+" "+n.className,i&&(t.style.marginLeft=-i.x+"px",t.style.marginTop=-i.y+"px"),s&&(t.style.width=s.x+"px",t.style.height=s.y+"px")},_createImg:function(t,i){return i=i||e.createElement("img"),i.src=t,i},_getIconUrl:function(t){return o.Browser.retina&&this.options[t+"RetinaUrl"]?this.options[t+"RetinaUrl"]:this.options[t+"Url"]}}),o.icon=function(t){return new o.Icon(t)},o.Icon.Default=o.Icon.extend({options:{iconSize:[25,41],iconAnchor:[12,41],popupAnchor:[1,-34],shadowSize:[41,41]},_getIconUrl:function(t){var e=t+"Url";if(this.options[e])return this.options[e];o.Browser.retina&&"icon"===t&&(t+="-2x");var i=o.Icon.Default.imagePath;if(!i)throw new Error("Couldn't autodetect L.Icon.Default.imagePath, set it manually.");return i+"/marker-"+t+".png"}}),o.Icon.Default.imagePath=function(){var t,i,n,o,s,a=e.getElementsByTagName("script"),r=/[\/^]leaflet[\-\._]?([\w\-\._]*)\.js\??/;for(t=0,i=a.length;i>t;t++)if(n=a[t].src,o=n.match(r))return s=n.split(r)[0],(s?s+"/":"")+"images"}(),o.Marker=o.Class.extend({includes:o.Mixin.Events,options:{icon:new o.Icon.Default,title:"",alt:"",clickable:!0,draggable:!1,keyboard:!0,zIndexOffset:0,opacity:1,riseOnHover:!1,riseOffset:250},initialize:function(t,e){o.setOptions(this,e),this._latlng=o.latLng(t)},onAdd:function(t){this._map=t,t.on("viewreset",this.update,this),this._initIcon(),this.update(),this.fire("add"),t.options.zoomAnimation&&t.options.markerZoomAnimation&&t.on("zoomanim",this._animateZoom,this)},addTo:function(t){return t.addLayer(this),this},onRemove:function(t){this.dragging&&this.dragging.disable(),this._removeIcon(),this._removeShadow(),this.fire("remove"),t.off({viewreset:this.update,zoomanim:this._animateZoom},this),this._map=null},getLatLng:function(){return this._latlng},setLatLng:function(t){return this._latlng=o.latLng(t),this.update(),this.fire("move",{latlng:this._latlng})},setZIndexOffset:function(t){return this.options.zIndexOffset=t,this.update(),this},setIcon:function(t){return this.options.icon=t,this._map&&(this._initIcon(),this.update()),this._popup&&this.bindPopup(this._popup),this},update:function(){if(this._icon){var t=this._map.latLngToLayerPoint(this._latlng).round();this._setPos(t)}return this},_initIcon:function(){var t=this.options,e=this._map,i=e.options.zoomAnimation&&e.options.markerZoomAnimation,n=i?"leaflet-zoom-animated":"leaflet-zoom-hide",s=t.icon.createIcon(this._icon),a=!1;s!==this._icon&&(this._icon&&this._removeIcon(),a=!0,t.title&&(s.title=t.title),t.alt&&(s.alt=t.alt)),o.DomUtil.addClass(s,n),t.keyboard&&(s.tabIndex="0"),this._icon=s,this._initInteraction(),t.riseOnHover&&o.DomEvent.on(s,"mouseover",this._bringToFront,this).on(s,"mouseout",this._resetZIndex,this);var r=t.icon.createShadow(this._shadow),h=!1;r!==this._shadow&&(this._removeShadow(),h=!0),r&&o.DomUtil.addClass(r,n),this._shadow=r,t.opacity<1&&this._updateOpacity();var l=this._map._panes;a&&l.markerPane.appendChild(this._icon),r&&h&&l.shadowPane.appendChild(this._shadow)},_removeIcon:function(){this.options.riseOnHover&&o.DomEvent.off(this._icon,"mouseover",this._bringToFront).off(this._icon,"mouseout",this._resetZIndex),this._map._panes.markerPane.removeChild(this._icon),this._icon=null},_removeShadow:function(){this._shadow&&this._map._panes.shadowPane.removeChild(this._shadow),this._shadow=null},_setPos:function(t){o.DomUtil.setPosition(this._icon,t),this._shadow&&o.DomUtil.setPosition(this._shadow,t),this._zIndex=t.y+this.options.zIndexOffset,this._resetZIndex()},_updateZIndex:function(t){this._icon.style.zIndex=this._zIndex+t},_animateZoom:function(t){var e=this._map._latLngToNewLayerPoint(this._latlng,t.zoom,t.center).round();this._setPos(e)},_initInteraction:function(){if(this.options.clickable){var t=this._icon,e=["dblclick","mousedown","mouseover","mouseout","contextmenu"];o.DomUtil.addClass(t,"leaflet-clickable"),o.DomEvent.on(t,"click",this._onMouseClick,this),o.DomEvent.on(t,"keypress",this._onKeyPress,this);for(var i=0;is?(e.height=s+"px",o.DomUtil.addClass(t,a)):o.DomUtil.removeClass(t,a),this._containerWidth=this._container.offsetWidth},_updatePosition:function(){if(this._map){var t=this._map.latLngToLayerPoint(this._latlng),e=this._animated,i=o.point(this.options.offset);e&&o.DomUtil.setPosition(this._container,t),this._containerBottom=-i.y-(e?0:t.y),this._containerLeft=-Math.round(this._containerWidth/2)+i.x+(e?0:t.x),this._container.style.bottom=this._containerBottom+"px",this._container.style.left=this._containerLeft+"px"}},_zoomAnimation:function(t){var e=this._map._latLngToNewLayerPoint(this._latlng,t.zoom,t.center);o.DomUtil.setPosition(this._container,e)},_adjustPan:function(){if(this.options.autoPan){var t=this._map,e=this._container.offsetHeight,i=this._containerWidth,n=new o.Point(this._containerLeft,-e-this._containerBottom);this._animated&&n._add(o.DomUtil.getPosition(this._container));var s=t.layerPointToContainerPoint(n),a=o.point(this.options.autoPanPadding),r=o.point(this.options.autoPanPaddingTopLeft||a),h=o.point(this.options.autoPanPaddingBottomRight||a),l=t.getSize(),u=0,c=0;s.x+i+h.x>l.x&&(u=s.x+i-l.x+h.x),s.x-u-r.x<0&&(u=s.x-r.x),s.y+e+h.y>l.y&&(c=s.y+e-l.y+h.y),s.y-c-r.y<0&&(c=s.y-r.y),(u||c)&&t.fire("autopanstart").panBy([u,c])}},_onCloseButtonClick:function(t){this._close(),o.DomEvent.stop(t)}}),o.popup=function(t,e){return new o.Popup(t,e)},o.Map.include({openPopup:function(t,e,i){if(this.closePopup(),!(t instanceof o.Popup)){var n=t;t=new o.Popup(i).setLatLng(e).setContent(n)}return t._isOpen=!0,this._popup=t,this.addLayer(t)},closePopup:function(t){return t&&t!==this._popup||(t=this._popup,this._popup=null),t&&(this.removeLayer(t),t._isOpen=!1),this}}),o.Marker.include({openPopup:function(){return this._popup&&this._map&&!this._map.hasLayer(this._popup)&&(this._popup.setLatLng(this._latlng),this._map.openPopup(this._popup)),this},closePopup:function(){return this._popup&&this._popup._close(),this},togglePopup:function(){return this._popup&&(this._popup._isOpen?this.closePopup():this.openPopup()),this},bindPopup:function(t,e){var i=o.point(this.options.icon.options.popupAnchor||[0,0]);return i=i.add(o.Popup.prototype.options.offset),e&&e.offset&&(i=i.add(e.offset)),e=o.extend({offset:i},e),this._popupHandlersAdded||(this.on("click",this.togglePopup,this).on("remove",this.closePopup,this).on("move",this._movePopup,this),this._popupHandlersAdded=!0),t instanceof o.Popup?(o.setOptions(t,e),this._popup=t):this._popup=new o.Popup(e,this).setContent(t),this},setPopupContent:function(t){return this._popup&&this._popup.setContent(t),this},unbindPopup:function(){return this._popup&&(this._popup=null,this.off("click",this.togglePopup,this).off("remove",this.closePopup,this).off("move",this._movePopup,this),this._popupHandlersAdded=!1),this},getPopup:function(){return this._popup},_movePopup:function(t){this._popup.setLatLng(t.latlng)}}),o.LayerGroup=o.Class.extend({initialize:function(t){this._layers={};var e,i;if(t)for(e=0,i=t.length;i>e;e++)this.addLayer(t[e])},addLayer:function(t){var e=this.getLayerId(t);return this._layers[e]=t,this._map&&this._map.addLayer(t),this},removeLayer:function(t){var e=t in this._layers?t:this.getLayerId(t);return this._map&&this._layers[e]&&this._map.removeLayer(this._layers[e]),delete this._layers[e],this},hasLayer:function(t){return t?t in this._layers||this.getLayerId(t)in this._layers:!1},clearLayers:function(){return this.eachLayer(this.removeLayer,this),this},invoke:function(t){var e,i,n=Array.prototype.slice.call(arguments,1);for(e in this._layers)i=this._layers[e],i[t]&&i[t].apply(i,n);return this},onAdd:function(t){this._map=t,this.eachLayer(t.addLayer,t)},onRemove:function(t){this.eachLayer(t.removeLayer,t),this._map=null},addTo:function(t){return t.addLayer(this),this},eachLayer:function(t,e){for(var i in this._layers)t.call(e,this._layers[i]);return this},getLayer:function(t){return this._layers[t]},getLayers:function(){var t=[];for(var e in this._layers)t.push(this._layers[e]);return t},setZIndex:function(t){return this.invoke("setZIndex",t)},getLayerId:function(t){return o.stamp(t)}}),o.layerGroup=function(t){return new o.LayerGroup(t)},o.FeatureGroup=o.LayerGroup.extend({includes:o.Mixin.Events,statics:{EVENTS:"click dblclick mouseover mouseout mousemove contextmenu popupopen popupclose"},addLayer:function(t){return this.hasLayer(t)?this:("on"in t&&t.on(o.FeatureGroup.EVENTS,this._propagateEvent,this),o.LayerGroup.prototype.addLayer.call(this,t),this._popupContent&&t.bindPopup&&t.bindPopup(this._popupContent,this._popupOptions),this.fire("layeradd",{layer:t}))},removeLayer:function(t){return this.hasLayer(t)?(t in this._layers&&(t=this._layers[t]),t.off(o.FeatureGroup.EVENTS,this._propagateEvent,this),o.LayerGroup.prototype.removeLayer.call(this,t),this._popupContent&&this.invoke("unbindPopup"),this.fire("layerremove",{layer:t})):this},bindPopup:function(t,e){return this._popupContent=t,this._popupOptions=e,this.invoke("bindPopup",t,e)},openPopup:function(t){for(var e in this._layers){this._layers[e].openPopup(t);break}return this},setStyle:function(t){return this.invoke("setStyle",t)},bringToFront:function(){return this.invoke("bringToFront")},bringToBack:function(){return this.invoke("bringToBack")},getBounds:function(){var t=new o.LatLngBounds;return this.eachLayer(function(e){t.extend(e instanceof o.Marker?e.getLatLng():e.getBounds())}),t},_propagateEvent:function(t){t=o.extend({layer:t.target,target:this},t),this.fire(t.type,t)}}),o.featureGroup=function(t){return new o.FeatureGroup(t)},o.Path=o.Class.extend({includes:[o.Mixin.Events],statics:{CLIP_PADDING:function(){var e=o.Browser.mobile?1280:2e3,i=(e/Math.max(t.outerWidth,t.outerHeight)-1)/2;return Math.max(0,Math.min(.5,i))}()},options:{stroke:!0,color:"#0033ff",dashArray:null,lineCap:null,lineJoin:null,weight:5,opacity:.5,fill:!1,fillColor:null,fillOpacity:.2,clickable:!0},initialize:function(t){o.setOptions(this,t)},onAdd:function(t){this._map=t,this._container||(this._initElements(),this._initEvents()),this.projectLatlngs(),this._updatePath(),this._container&&this._map._pathRoot.appendChild(this._container),this.fire("add"),t.on({viewreset:this.projectLatlngs,moveend:this._updatePath},this)},addTo:function(t){return t.addLayer(this),this},onRemove:function(t){t._pathRoot.removeChild(this._container),this.fire("remove"),this._map=null,o.Browser.vml&&(this._container=null,this._stroke=null,this._fill=null),t.off({viewreset:this.projectLatlngs,moveend:this._updatePath},this)},projectLatlngs:function(){},setStyle:function(t){return o.setOptions(this,t),this._container&&this._updateStyle(),this},redraw:function(){return this._map&&(this.projectLatlngs(),this._updatePath()),this}}),o.Map.include({_updatePathViewport:function(){var t=o.Path.CLIP_PADDING,e=this.getSize(),i=o.DomUtil.getPosition(this._mapPane),n=i.multiplyBy(-1)._subtract(e.multiplyBy(t)._round()),s=n.add(e.multiplyBy(1+2*t)._round());this._pathViewport=new o.Bounds(n,s)}}),o.Path.SVG_NS="http://www.w3.org/2000/svg",o.Browser.svg=!(!e.createElementNS||!e.createElementNS(o.Path.SVG_NS,"svg").createSVGRect),o.Path=o.Path.extend({statics:{SVG:o.Browser.svg},bringToFront:function(){var t=this._map._pathRoot,e=this._container;return e&&t.lastChild!==e&&t.appendChild(e),this},bringToBack:function(){var t=this._map._pathRoot,e=this._container,i=t.firstChild;return e&&i!==e&&t.insertBefore(e,i),this},getPathString:function(){},_createElement:function(t){return e.createElementNS(o.Path.SVG_NS,t)},_initElements:function(){this._map._initPathRoot(),this._initPath(),this._initStyle()},_initPath:function(){this._container=this._createElement("g"),this._path=this._createElement("path"),this.options.className&&o.DomUtil.addClass(this._path,this.options.className),this._container.appendChild(this._path)},_initStyle:function(){this.options.stroke&&(this._path.setAttribute("stroke-linejoin","round"),this._path.setAttribute("stroke-linecap","round")),this.options.fill&&this._path.setAttribute("fill-rule","evenodd"),this.options.pointerEvents&&this._path.setAttribute("pointer-events",this.options.pointerEvents),this.options.clickable||this.options.pointerEvents||this._path.setAttribute("pointer-events","none"),this._updateStyle()},_updateStyle:function(){this.options.stroke?(this._path.setAttribute("stroke",this.options.color),this._path.setAttribute("stroke-opacity",this.options.opacity),this._path.setAttribute("stroke-width",this.options.weight),this.options.dashArray?this._path.setAttribute("stroke-dasharray",this.options.dashArray):this._path.removeAttribute("stroke-dasharray"),this.options.lineCap&&this._path.setAttribute("stroke-linecap",this.options.lineCap),this.options.lineJoin&&this._path.setAttribute("stroke-linejoin",this.options.lineJoin)):this._path.setAttribute("stroke","none"),this.options.fill?(this._path.setAttribute("fill",this.options.fillColor||this.options.color),this._path.setAttribute("fill-opacity",this.options.fillOpacity)):this._path.setAttribute("fill","none")},_updatePath:function(){var t=this.getPathString();t||(t="M0 0"),this._path.setAttribute("d",t)},_initEvents:function(){if(this.options.clickable){(o.Browser.svg||!o.Browser.vml)&&o.DomUtil.addClass(this._path,"leaflet-clickable"),o.DomEvent.on(this._container,"click",this._onMouseClick,this);for(var t=["dblclick","mousedown","mouseover","mouseout","mousemove","contextmenu"],e=0;e';var i=t.firstChild;return i.style.behavior="url(#default#VML)",i&&"object"==typeof i.adj}catch(n){return!1}}(),o.Path=o.Browser.svg||!o.Browser.vml?o.Path:o.Path.extend({statics:{VML:!0,CLIP_PADDING:.02},_createElement:function(){try{return e.namespaces.add("lvml","urn:schemas-microsoft-com:vml"),function(t){return e.createElement("')}}catch(t){return function(t){return e.createElement("<"+t+' xmlns="urn:schemas-microsoft.com:vml" class="lvml">')}}}(),_initPath:function(){var t=this._container=this._createElement("shape");o.DomUtil.addClass(t,"leaflet-vml-shape"+(this.options.className?" "+this.options.className:"")),this.options.clickable&&o.DomUtil.addClass(t,"leaflet-clickable"),t.coordsize="1 1",this._path=this._createElement("path"),t.appendChild(this._path),this._map._pathRoot.appendChild(t)},_initStyle:function(){this._updateStyle()},_updateStyle:function(){var t=this._stroke,e=this._fill,i=this.options,n=this._container;n.stroked=i.stroke,n.filled=i.fill,i.stroke?(t||(t=this._stroke=this._createElement("stroke"),t.endcap="round",n.appendChild(t)),t.weight=i.weight+"px",t.color=i.color,t.opacity=i.opacity,t.dashStyle=i.dashArray?o.Util.isArray(i.dashArray)?i.dashArray.join(" "):i.dashArray.replace(/( *, *)/g," "):"",i.lineCap&&(t.endcap=i.lineCap.replace("butt","flat")),i.lineJoin&&(t.joinstyle=i.lineJoin)):t&&(n.removeChild(t),this._stroke=null),i.fill?(e||(e=this._fill=this._createElement("fill"),n.appendChild(e)),e.color=i.fillColor||i.color,e.opacity=i.fillOpacity):e&&(n.removeChild(e),this._fill=null)},_updatePath:function(){var t=this._container.style;t.display="none",this._path.v=this.getPathString()+" ",t.display=""}}),o.Map.include(o.Browser.svg||!o.Browser.vml?{}:{_initPathRoot:function(){if(!this._pathRoot){var t=this._pathRoot=e.createElement("div");t.className="leaflet-vml-container",this._panes.overlayPane.appendChild(t),this.on("moveend",this._updatePathViewport),this._updatePathViewport()}}}),o.Browser.canvas=function(){return!!e.createElement("canvas").getContext}(),o.Path=o.Path.SVG&&!t.L_PREFER_CANVAS||!o.Browser.canvas?o.Path:o.Path.extend({statics:{CANVAS:!0,SVG:!1},redraw:function(){return this._map&&(this.projectLatlngs(),this._requestUpdate()),this},setStyle:function(t){return o.setOptions(this,t),this._map&&(this._updateStyle(),this._requestUpdate()),this},onRemove:function(t){t.off("viewreset",this.projectLatlngs,this).off("moveend",this._updatePath,this),this.options.clickable&&(this._map.off("click",this._onClick,this),this._map.off("mousemove",this._onMouseMove,this)),this._requestUpdate(),this._map=null},_requestUpdate:function(){this._map&&!o.Path._updateRequest&&(o.Path._updateRequest=o.Util.requestAnimFrame(this._fireMapMoveEnd,this._map))},_fireMapMoveEnd:function(){o.Path._updateRequest=null,this.fire("moveend")},_initElements:function(){this._map._initPathRoot(),this._ctx=this._map._canvasCtx},_updateStyle:function(){var t=this.options;t.stroke&&(this._ctx.lineWidth=t.weight,this._ctx.strokeStyle=t.color),t.fill&&(this._ctx.fillStyle=t.fillColor||t.color)},_drawPath:function(){var t,e,i,n,s,a;for(this._ctx.beginPath(),t=0,i=this._parts.length;i>t;t++){for(e=0,n=this._parts[t].length;n>e;e++)s=this._parts[t][e],a=(0===e?"move":"line")+"To",this._ctx[a](s.x,s.y);this instanceof o.Polygon&&this._ctx.closePath()}},_checkIfEmpty:function(){return!this._parts.length},_updatePath:function(){if(!this._checkIfEmpty()){var t=this._ctx,e=this.options;this._drawPath(),t.save(),this._updateStyle(),e.fill&&(t.globalAlpha=e.fillOpacity,t.fill()),e.stroke&&(t.globalAlpha=e.opacity,t.stroke()),t.restore()}},_initEvents:function(){this.options.clickable&&(this._map.on("mousemove",this._onMouseMove,this),this._map.on("click",this._onClick,this))},_onClick:function(t){this._containsPoint(t.layerPoint)&&this.fire("click",t)},_onMouseMove:function(t){this._map&&!this._map._animatingZoom&&(this._containsPoint(t.layerPoint)?(this._ctx.canvas.style.cursor="pointer",this._mouseInside=!0,this.fire("mouseover",t)):this._mouseInside&&(this._ctx.canvas.style.cursor="",this._mouseInside=!1,this.fire("mouseout",t)))}}),o.Map.include(o.Path.SVG&&!t.L_PREFER_CANVAS||!o.Browser.canvas?{}:{_initPathRoot:function(){var t,i=this._pathRoot;i||(i=this._pathRoot=e.createElement("canvas"),i.style.position="absolute",t=this._canvasCtx=i.getContext("2d"),t.lineCap="round",t.lineJoin="round",this._panes.overlayPane.appendChild(i),this.options.zoomAnimation&&(this._pathRoot.className="leaflet-zoom-animated",this.on("zoomanim",this._animatePathZoom),this.on("zoomend",this._endPathZoom)),this.on("moveend",this._updateCanvasViewport),this._updateCanvasViewport())},_updateCanvasViewport:function(){if(!this._pathZooming){this._updatePathViewport();var t=this._pathViewport,e=t.min,i=t.max.subtract(e),n=this._pathRoot;o.DomUtil.setPosition(n,e),n.width=i.x,n.height=i.y,n.getContext("2d").translate(-e.x,-e.y)}}}),o.LineUtil={simplify:function(t,e){if(!e||!t.length)return t.slice();var i=e*e;return t=this._reducePoints(t,i),t=this._simplifyDP(t,i)},pointToSegmentDistance:function(t,e,i){return Math.sqrt(this._sqClosestPointOnSegment(t,e,i,!0))},closestPointOnSegment:function(t,e,i){return this._sqClosestPointOnSegment(t,e,i)},_simplifyDP:function(t,e){var n=t.length,o=typeof Uint8Array!=i+""?Uint8Array:Array,s=new o(n);s[0]=s[n-1]=1,this._simplifyDPStep(t,s,e,0,n-1);var a,r=[];for(a=0;n>a;a++)s[a]&&r.push(t[a]);return r},_simplifyDPStep:function(t,e,i,n,o){var s,a,r,h=0;for(a=n+1;o-1>=a;a++)r=this._sqClosestPointOnSegment(t[a],t[n],t[o],!0),r>h&&(s=a,h=r);h>i&&(e[s]=1,this._simplifyDPStep(t,e,i,n,s),this._simplifyDPStep(t,e,i,s,o))},_reducePoints:function(t,e){for(var i=[t[0]],n=1,o=0,s=t.length;s>n;n++)this._sqDist(t[n],t[o])>e&&(i.push(t[n]),o=n);return s-1>o&&i.push(t[s-1]),i},clipSegment:function(t,e,i,n){var o,s,a,r=n?this._lastCode:this._getBitCode(t,i),h=this._getBitCode(e,i);for(this._lastCode=h;;){if(!(r|h))return[t,e];if(r&h)return!1;o=r||h,s=this._getEdgeIntersection(t,e,o,i),a=this._getBitCode(s,i),o===r?(t=s,r=a):(e=s,h=a)}},_getEdgeIntersection:function(t,e,i,n){var s=e.x-t.x,a=e.y-t.y,r=n.min,h=n.max;return 8&i?new o.Point(t.x+s*(h.y-t.y)/a,h.y):4&i?new o.Point(t.x+s*(r.y-t.y)/a,r.y):2&i?new o.Point(h.x,t.y+a*(h.x-t.x)/s):1&i?new o.Point(r.x,t.y+a*(r.x-t.x)/s):void 0},_getBitCode:function(t,e){var i=0;return t.xe.max.x&&(i|=2),t.ye.max.y&&(i|=8),i},_sqDist:function(t,e){var i=e.x-t.x,n=e.y-t.y;return i*i+n*n},_sqClosestPointOnSegment:function(t,e,i,n){var s,a=e.x,r=e.y,h=i.x-a,l=i.y-r,u=h*h+l*l;return u>0&&(s=((t.x-a)*h+(t.y-r)*l)/u,s>1?(a=i.x,r=i.y):s>0&&(a+=h*s,r+=l*s)),h=t.x-a,l=t.y-r,n?h*h+l*l:new o.Point(a,r)}},o.Polyline=o.Path.extend({initialize:function(t,e){o.Path.prototype.initialize.call(this,e),this._latlngs=this._convertLatLngs(t)},options:{smoothFactor:1,noClip:!1},projectLatlngs:function(){this._originalPoints=[];for(var t=0,e=this._latlngs.length;e>t;t++)this._originalPoints[t]=this._map.latLngToLayerPoint(this._latlngs[t])},getPathString:function(){for(var t=0,e=this._parts.length,i="";e>t;t++)i+=this._getPathPartStr(this._parts[t]);return i},getLatLngs:function(){return this._latlngs},setLatLngs:function(t){return this._latlngs=this._convertLatLngs(t),this.redraw()},addLatLng:function(t){return this._latlngs.push(o.latLng(t)),this.redraw()},spliceLatLngs:function(){var t=[].splice.apply(this._latlngs,arguments);return this._convertLatLngs(this._latlngs,!0),this.redraw(),t},closestLayerPoint:function(t){for(var e,i,n=1/0,s=this._parts,a=null,r=0,h=s.length;h>r;r++)for(var l=s[r],u=1,c=l.length;c>u;u++){e=l[u-1],i=l[u];var d=o.LineUtil._sqClosestPointOnSegment(t,e,i,!0);n>d&&(n=d,a=o.LineUtil._sqClosestPointOnSegment(t,e,i))}return a&&(a.distance=Math.sqrt(n)),a},getBounds:function(){return new o.LatLngBounds(this.getLatLngs())},_convertLatLngs:function(t,e){var i,n,s=e?t:[];for(i=0,n=t.length;n>i;i++){if(o.Util.isArray(t[i])&&"number"!=typeof t[i][0])return;s[i]=o.latLng(t[i])}return s},_initEvents:function(){o.Path.prototype._initEvents.call(this)},_getPathPartStr:function(t){for(var e,i=o.Path.VML,n=0,s=t.length,a="";s>n;n++)e=t[n],i&&e._round(),a+=(n?"L":"M")+e.x+" "+e.y;return a},_clipPoints:function(){var t,e,i,n=this._originalPoints,s=n.length;if(this.options.noClip)return this._parts=[n],void 0;this._parts=[];var a=this._parts,r=this._map._pathViewport,h=o.LineUtil;for(t=0,e=0;s-1>t;t++)i=h.clipSegment(n[t],n[t+1],r,t),i&&(a[e]=a[e]||[],a[e].push(i[0]),(i[1]!==n[t+1]||t===s-2)&&(a[e].push(i[1]),e++))},_simplifyPoints:function(){for(var t=this._parts,e=o.LineUtil,i=0,n=t.length;n>i;i++)t[i]=e.simplify(t[i],this.options.smoothFactor)},_updatePath:function(){this._map&&(this._clipPoints(),this._simplifyPoints(),o.Path.prototype._updatePath.call(this))}}),o.polyline=function(t,e){return new o.Polyline(t,e)},o.PolyUtil={},o.PolyUtil.clipPolygon=function(t,e){var i,n,s,a,r,h,l,u,c,d=[1,4,2,8],p=o.LineUtil;for(n=0,l=t.length;l>n;n++)t[n]._code=p._getBitCode(t[n],e);for(a=0;4>a;a++){for(u=d[a],i=[],n=0,l=t.length,s=l-1;l>n;s=n++)r=t[n],h=t[s],r._code&u?h._code&u||(c=p._getEdgeIntersection(h,r,u,e),c._code=p._getBitCode(c,e),i.push(c)):(h._code&u&&(c=p._getEdgeIntersection(h,r,u,e),c._code=p._getBitCode(c,e),i.push(c)),i.push(r));t=i}return t},o.Polygon=o.Polyline.extend({options:{fill:!0},initialize:function(t,e){o.Polyline.prototype.initialize.call(this,t,e),this._initWithHoles(t)},_initWithHoles:function(t){var e,i,n;if(t&&o.Util.isArray(t[0])&&"number"!=typeof t[0][0])for(this._latlngs=this._convertLatLngs(t[0]),this._holes=t.slice(1),e=0,i=this._holes.length;i>e;e++)n=this._holes[e]=this._convertLatLngs(this._holes[e]),n[0].equals(n[n.length-1])&&n.pop();t=this._latlngs,t.length>=2&&t[0].equals(t[t.length-1])&&t.pop()},projectLatlngs:function(){if(o.Polyline.prototype.projectLatlngs.call(this),this._holePoints=[],this._holes){var t,e,i,n;for(t=0,i=this._holes.length;i>t;t++)for(this._holePoints[t]=[],e=0,n=this._holes[t].length;n>e;e++)this._holePoints[t][e]=this._map.latLngToLayerPoint(this._holes[t][e])}},setLatLngs:function(t){return t&&o.Util.isArray(t[0])&&"number"!=typeof t[0][0]?(this._initWithHoles(t),this.redraw()):o.Polyline.prototype.setLatLngs.call(this,t)},_clipPoints:function(){var t=this._originalPoints,e=[];if(this._parts=[t].concat(this._holePoints),!this.options.noClip){for(var i=0,n=this._parts.length;n>i;i++){var s=o.PolyUtil.clipPolygon(this._parts[i],this._map._pathViewport);s.length&&e.push(s)}this._parts=e}},_getPathPartStr:function(t){var e=o.Polyline.prototype._getPathPartStr.call(this,t);return e+(o.Browser.svg?"z":"x")}}),o.polygon=function(t,e){return new o.Polygon(t,e)},function(){function t(t){return o.FeatureGroup.extend({initialize:function(t,e){this._layers={},this._options=e,this.setLatLngs(t)},setLatLngs:function(e){var i=0,n=e.length;for(this.eachLayer(function(t){n>i?t.setLatLngs(e[i++]):this.removeLayer(t)},this);n>i;)this.addLayer(new t(e[i++],this._options));return this},getLatLngs:function(){var t=[];return this.eachLayer(function(e){t.push(e.getLatLngs())}),t}})}o.MultiPolyline=t(o.Polyline),o.MultiPolygon=t(o.Polygon),o.multiPolyline=function(t,e){return new o.MultiPolyline(t,e)},o.multiPolygon=function(t,e){return new o.MultiPolygon(t,e)}}(),o.Rectangle=o.Polygon.extend({initialize:function(t,e){o.Polygon.prototype.initialize.call(this,this._boundsToLatLngs(t),e)},setBounds:function(t){this.setLatLngs(this._boundsToLatLngs(t))},_boundsToLatLngs:function(t){return t=o.latLngBounds(t),[t.getSouthWest(),t.getNorthWest(),t.getNorthEast(),t.getSouthEast()]}}),o.rectangle=function(t,e){return new o.Rectangle(t,e)},o.Circle=o.Path.extend({initialize:function(t,e,i){o.Path.prototype.initialize.call(this,i),this._latlng=o.latLng(t),this._mRadius=e},options:{fill:!0},setLatLng:function(t){return this._latlng=o.latLng(t),this.redraw()},setRadius:function(t){return this._mRadius=t,this.redraw()},projectLatlngs:function(){var t=this._getLngRadius(),e=this._latlng,i=this._map.latLngToLayerPoint([e.lat,e.lng-t]);this._point=this._map.latLngToLayerPoint(e),this._radius=Math.max(this._point.x-i.x,1)},getBounds:function(){var t=this._getLngRadius(),e=this._mRadius/40075017*360,i=this._latlng;return new o.LatLngBounds([i.lat-e,i.lng-t],[i.lat+e,i.lng+t])},getLatLng:function(){return this._latlng},getPathString:function(){var t=this._point,e=this._radius;return this._checkIfEmpty()?"":o.Browser.svg?"M"+t.x+","+(t.y-e)+"A"+e+","+e+",0,1,1,"+(t.x-.1)+","+(t.y-e)+" z":(t._round(),e=Math.round(e),"AL "+t.x+","+t.y+" "+e+","+e+" 0,23592600")},getRadius:function(){return this._mRadius},_getLatRadius:function(){return this._mRadius/40075017*360},_getLngRadius:function(){return this._getLatRadius()/Math.cos(o.LatLng.DEG_TO_RAD*this._latlng.lat)},_checkIfEmpty:function(){if(!this._map)return!1;var t=this._map._pathViewport,e=this._radius,i=this._point;return i.x-e>t.max.x||i.y-e>t.max.y||i.x+ei;i++)for(l=this._parts[i],n=0,r=l.length,s=r-1;r>n;s=n++)if((e||0!==n)&&(h=o.LineUtil.pointToSegmentDistance(t,l[s],l[n]),u>=h))return!0;return!1}}:{}),o.Polygon.include(o.Path.CANVAS?{_containsPoint:function(t){var e,i,n,s,a,r,h,l,u=!1;if(o.Polyline.prototype._containsPoint.call(this,t,!0))return!0;for(s=0,h=this._parts.length;h>s;s++)for(e=this._parts[s],a=0,l=e.length,r=l-1;l>a;r=a++)i=e[a],n=e[r],i.y>t.y!=n.y>t.y&&t.x<(n.x-i.x)*(t.y-i.y)/(n.y-i.y)+i.x&&(u=!u);return u}}:{}),o.Circle.include(o.Path.CANVAS?{_drawPath:function(){var t=this._point;this._ctx.beginPath(),this._ctx.arc(t.x,t.y,this._radius,0,2*Math.PI,!1)},_containsPoint:function(t){var e=this._point,i=this.options.stroke?this.options.weight/2:0;return t.distanceTo(e)<=this._radius+i}}:{}),o.CircleMarker.include(o.Path.CANVAS?{_updateStyle:function(){o.Path.prototype._updateStyle.call(this)}}:{}),o.GeoJSON=o.FeatureGroup.extend({initialize:function(t,e){o.setOptions(this,e),this._layers={},t&&this.addData(t)},addData:function(t){var e,i,n,s=o.Util.isArray(t)?t:t.features;if(s){for(e=0,i=s.length;i>e;e++)n=s[e],(n.geometries||n.geometry||n.features||n.coordinates)&&this.addData(s[e]);return this}var a=this.options;if(!a.filter||a.filter(t)){var r=o.GeoJSON.geometryToLayer(t,a.pointToLayer,a.coordsToLatLng,a);return r.feature=o.GeoJSON.asFeature(t),r.defaultOptions=r.options,this.resetStyle(r),a.onEachFeature&&a.onEachFeature(t,r),this.addLayer(r)}},resetStyle:function(t){var e=this.options.style;e&&(o.Util.extend(t.options,t.defaultOptions),this._setLayerStyle(t,e))},setStyle:function(t){this.eachLayer(function(e){this._setLayerStyle(e,t)},this)},_setLayerStyle:function(t,e){"function"==typeof e&&(e=e(t.feature)),t.setStyle&&t.setStyle(e)}}),o.extend(o.GeoJSON,{geometryToLayer:function(t,e,i,n){var s,a,r,h,l="Feature"===t.type?t.geometry:t,u=l.coordinates,c=[];switch(i=i||this.coordsToLatLng,l.type){case"Point":return s=i(u),e?e(t,s):new o.Marker(s);case"MultiPoint":for(r=0,h=u.length;h>r;r++)s=i(u[r]),c.push(e?e(t,s):new o.Marker(s));return new o.FeatureGroup(c);case"LineString":return a=this.coordsToLatLngs(u,0,i),new o.Polyline(a,n);case"Polygon":if(2===u.length&&!u[1].length)throw new Error("Invalid GeoJSON object.");return a=this.coordsToLatLngs(u,1,i),new o.Polygon(a,n);case"MultiLineString":return a=this.coordsToLatLngs(u,1,i),new o.MultiPolyline(a,n);case"MultiPolygon":return a=this.coordsToLatLngs(u,2,i),new o.MultiPolygon(a,n);case"GeometryCollection":for(r=0,h=l.geometries.length;h>r;r++)c.push(this.geometryToLayer({geometry:l.geometries[r],type:"Feature",properties:t.properties},e,i,n));return new o.FeatureGroup(c);default:throw new Error("Invalid GeoJSON object.")}},coordsToLatLng:function(t){return new o.LatLng(t[1],t[0],t[2])},coordsToLatLngs:function(t,e,i){var n,o,s,a=[];for(o=0,s=t.length;s>o;o++)n=e?this.coordsToLatLngs(t[o],e-1,i):(i||this.coordsToLatLng)(t[o]),a.push(n);return a},latLngToCoords:function(t){var e=[t.lng,t.lat];return t.alt!==i&&e.push(t.alt),e},latLngsToCoords:function(t){for(var e=[],i=0,n=t.length;n>i;i++)e.push(o.GeoJSON.latLngToCoords(t[i]));return e},getFeature:function(t,e){return t.feature?o.extend({},t.feature,{geometry:e}):o.GeoJSON.asFeature(e)},asFeature:function(t){return"Feature"===t.type?t:{type:"Feature",properties:{},geometry:t}}});var a={toGeoJSON:function(){return o.GeoJSON.getFeature(this,{type:"Point",coordinates:o.GeoJSON.latLngToCoords(this.getLatLng())})}};o.Marker.include(a),o.Circle.include(a),o.CircleMarker.include(a),o.Polyline.include({toGeoJSON:function(){return o.GeoJSON.getFeature(this,{type:"LineString",coordinates:o.GeoJSON.latLngsToCoords(this.getLatLngs())})}}),o.Polygon.include({toGeoJSON:function(){var t,e,i,n=[o.GeoJSON.latLngsToCoords(this.getLatLngs())];if(n[0].push(n[0][0]),this._holes)for(t=0,e=this._holes.length;e>t;t++)i=o.GeoJSON.latLngsToCoords(this._holes[t]),i.push(i[0]),n.push(i);return o.GeoJSON.getFeature(this,{type:"Polygon",coordinates:n})}}),function(){function t(t){return function(){var e=[];return this.eachLayer(function(t){e.push(t.toGeoJSON().geometry.coordinates)}),o.GeoJSON.getFeature(this,{type:t,coordinates:e})}}o.MultiPolyline.include({toGeoJSON:t("MultiLineString")}),o.MultiPolygon.include({toGeoJSON:t("MultiPolygon")}),o.LayerGroup.include({toGeoJSON:function(){var e,i=this.feature&&this.feature.geometry,n=[];if(i&&"MultiPoint"===i.type)return t("MultiPoint").call(this);var s=i&&"GeometryCollection"===i.type;return this.eachLayer(function(t){t.toGeoJSON&&(e=t.toGeoJSON(),n.push(s?e.geometry:o.GeoJSON.asFeature(e)))}),s?o.GeoJSON.getFeature(this,{geometries:n,type:"GeometryCollection"}):{type:"FeatureCollection",features:n}}})}(),o.geoJson=function(t,e){return new o.GeoJSON(t,e)},o.DomEvent={addListener:function(t,e,i,n){var s,a,r,h=o.stamp(i),l="_leaflet_"+e+h;return t[l]?this:(s=function(e){return i.call(n||t,e||o.DomEvent._getEvent())},o.Browser.pointer&&0===e.indexOf("touch")?this.addPointerListener(t,e,s,h):(o.Browser.touch&&"dblclick"===e&&this.addDoubleTapListener&&this.addDoubleTapListener(t,s,h),"addEventListener"in t?"mousewheel"===e?(t.addEventListener("DOMMouseScroll",s,!1),t.addEventListener(e,s,!1)):"mouseenter"===e||"mouseleave"===e?(a=s,r="mouseenter"===e?"mouseover":"mouseout",s=function(e){return o.DomEvent._checkMouse(t,e)?a(e):void 0},t.addEventListener(r,s,!1)):"click"===e&&o.Browser.android?(a=s,s=function(t){return o.DomEvent._filterClick(t,a)},t.addEventListener(e,s,!1)):t.addEventListener(e,s,!1):"attachEvent"in t&&t.attachEvent("on"+e,s),t[l]=s,this))},removeListener:function(t,e,i){var n=o.stamp(i),s="_leaflet_"+e+n,a=t[s];return a?(o.Browser.pointer&&0===e.indexOf("touch")?this.removePointerListener(t,e,n):o.Browser.touch&&"dblclick"===e&&this.removeDoubleTapListener?this.removeDoubleTapListener(t,n):"removeEventListener"in t?"mousewheel"===e?(t.removeEventListener("DOMMouseScroll",a,!1),t.removeEventListener(e,a,!1)):"mouseenter"===e||"mouseleave"===e?t.removeEventListener("mouseenter"===e?"mouseover":"mouseout",a,!1):t.removeEventListener(e,a,!1):"detachEvent"in t&&t.detachEvent("on"+e,a),t[s]=null,this):this},stopPropagation:function(t){return t.stopPropagation?t.stopPropagation():t.cancelBubble=!0,o.DomEvent._skipped(t),this},disableScrollPropagation:function(t){var e=o.DomEvent.stopPropagation;return o.DomEvent.on(t,"mousewheel",e).on(t,"MozMousePixelScroll",e)},disableClickPropagation:function(t){for(var e=o.DomEvent.stopPropagation,i=o.Draggable.START.length-1;i>=0;i--)o.DomEvent.on(t,o.Draggable.START[i],e);return o.DomEvent.on(t,"click",o.DomEvent._fakeStop).on(t,"dblclick",e)},preventDefault:function(t){return t.preventDefault?t.preventDefault():t.returnValue=!1,this},stop:function(t){return o.DomEvent.preventDefault(t).stopPropagation(t)},getMousePosition:function(t,i){var n=e.body,s=e.documentElement,a=o.DomUtil.documentIsLtr()?t.pageX?t.pageX-n.scrollLeft-s.scrollLeft:t.clientX:o.Browser.gecko?t.pageX-n.scrollLeft-s.scrollLeft:t.pageX?t.pageX-n.scrollLeft+s.scrollLeft:t.clientX,r=t.pageY?t.pageY-n.scrollTop-s.scrollTop:t.clientY,h=new o.Point(a,r);if(!i)return h;var l=i.getBoundingClientRect(),u=l.left-i.clientLeft,c=l.top-i.clientTop;return h._subtract(new o.Point(u,c))},getWheelDelta:function(t){var e=0;return t.wheelDelta&&(e=t.wheelDelta/120),t.detail&&(e=-t.detail/3),e},_skipEvents:{},_fakeStop:function(t){o.DomEvent._skipEvents[t.type]=!0},_skipped:function(t){var e=this._skipEvents[t.type];return this._skipEvents[t.type]=!1,e},_checkMouse:function(t,e){var i=e.relatedTarget;if(!i)return!0;try{for(;i&&i!==t;)i=i.parentNode}catch(n){return!1}return i!==t},_getEvent:function(){var e=t.event;if(!e)for(var i=arguments.callee.caller;i&&(e=i.arguments[0],!e||t.Event!==e.constructor);)i=i.caller;return e},_filterClick:function(t,e){var i=t.timeStamp||t.originalEvent.timeStamp,n=o.DomEvent._lastClick&&i-o.DomEvent._lastClick;return n&&n>100&&1e3>n||t.target._simulatedClick&&!t._simulated?(o.DomEvent.stop(t),void 0):(o.DomEvent._lastClick=i,e(t))}},o.DomEvent.on=o.DomEvent.addListener,o.DomEvent.off=o.DomEvent.removeListener,o.Draggable=o.Class.extend({includes:o.Mixin.Events,statics:{START:o.Browser.touch?["touchstart","mousedown"]:["mousedown"],END:{mousedown:"mouseup",touchstart:"touchend",pointerdown:"touchend",MSPointerDown:"touchend"},MOVE:{mousedown:"mousemove",touchstart:"touchmove",pointerdown:"touchmove",MSPointerDown:"touchmove"}},initialize:function(t,e){this._element=t,this._dragStartTarget=e||t},enable:function(){if(!this._enabled){for(var t=o.Draggable.START.length-1;t>=0;t--)o.DomEvent.on(this._dragStartTarget,o.Draggable.START[t],this._onDown,this);this._enabled=!0}},disable:function(){if(this._enabled){for(var t=o.Draggable.START.length-1;t>=0;t--)o.DomEvent.off(this._dragStartTarget,o.Draggable.START[t],this._onDown,this);this._enabled=!1,this._moved=!1}},_onDown:function(t){if(this._moved=!1,!(t.shiftKey||1!==t.which&&1!==t.button&&!t.touches||(o.DomEvent.stopPropagation(t),o.Draggable._disabled||(o.DomUtil.disableImageDrag(),o.DomUtil.disableTextSelection(),this._moving)))){var i=t.touches?t.touches[0]:t;this._startPoint=new o.Point(i.clientX,i.clientY),this._startPos=this._newPos=o.DomUtil.getPosition(this._element),o.DomEvent.on(e,o.Draggable.MOVE[t.type],this._onMove,this).on(e,o.Draggable.END[t.type],this._onUp,this)}},_onMove:function(t){if(t.touches&&t.touches.length>1)return this._moved=!0,void 0;var i=t.touches&&1===t.touches.length?t.touches[0]:t,n=new o.Point(i.clientX,i.clientY),s=n.subtract(this._startPoint);(s.x||s.y)&&(o.DomEvent.preventDefault(t),this._moved||(this.fire("dragstart"),this._moved=!0,this._startPos=o.DomUtil.getPosition(this._element).subtract(s),o.DomUtil.addClass(e.body,"leaflet-dragging"),o.DomUtil.addClass(t.target||t.srcElement,"leaflet-drag-target")),this._newPos=this._startPos.add(s),this._moving=!0,o.Util.cancelAnimFrame(this._animRequest),this._animRequest=o.Util.requestAnimFrame(this._updatePosition,this,!0,this._dragStartTarget))},_updatePosition:function(){this.fire("predrag"),o.DomUtil.setPosition(this._element,this._newPos),this.fire("drag")},_onUp:function(t){o.DomUtil.removeClass(e.body,"leaflet-dragging"),o.DomUtil.removeClass(t.target||t.srcElement,"leaflet-drag-target");for(var i in o.Draggable.MOVE)o.DomEvent.off(e,o.Draggable.MOVE[i],this._onMove).off(e,o.Draggable.END[i],this._onUp);o.DomUtil.enableImageDrag(),o.DomUtil.enableTextSelection(),this._moved&&this._moving&&(o.Util.cancelAnimFrame(this._animRequest),this.fire("dragend",{distance:this._newPos.distanceTo(this._startPos)})),this._moving=!1}}),o.Handler=o.Class.extend({initialize:function(t){this._map=t},enable:function(){this._enabled||(this._enabled=!0,this.addHooks())},disable:function(){this._enabled&&(this._enabled=!1,this.removeHooks())},enabled:function(){return!!this._enabled}}),o.Map.mergeOptions({dragging:!0,inertia:!o.Browser.android23,inertiaDeceleration:3400,inertiaMaxSpeed:1/0,inertiaThreshold:o.Browser.touch?32:18,easeLinearity:.25,worldCopyJump:!1}),o.Map.Drag=o.Handler.extend({addHooks:function(){if(!this._draggable){var t=this._map;this._draggable=new o.Draggable(t._mapPane,t._container),this._draggable.on({dragstart:this._onDragStart,drag:this._onDrag,dragend:this._onDragEnd},this),t.options.worldCopyJump&&(this._draggable.on("predrag",this._onPreDrag,this),t.on("viewreset",this._onViewReset,this),t.whenReady(this._onViewReset,this))}this._draggable.enable()},removeHooks:function(){this._draggable.disable()},moved:function(){return this._draggable&&this._draggable._moved},_onDragStart:function(){var t=this._map;t._panAnim&&t._panAnim.stop(),t.fire("movestart").fire("dragstart"),t.options.inertia&&(this._positions=[],this._times=[])},_onDrag:function(){if(this._map.options.inertia){var t=this._lastTime=+new Date,e=this._lastPos=this._draggable._newPos;this._positions.push(e),this._times.push(t),t-this._times[0]>200&&(this._positions.shift(),this._times.shift())}this._map.fire("move").fire("drag")},_onViewReset:function(){var t=this._map.getSize()._divideBy(2),e=this._map.latLngToLayerPoint([0,0]);this._initialWorldOffset=e.subtract(t).x,this._worldWidth=this._map.project([0,180]).x},_onPreDrag:function(){var t=this._worldWidth,e=Math.round(t/2),i=this._initialWorldOffset,n=this._draggable._newPos.x,o=(n-e+i)%t+e-i,s=(n+e+i)%t-e-i,a=Math.abs(o+i)i.inertiaThreshold||!this._positions[0];if(e.fire("dragend",t),s)e.fire("moveend");else{var a=this._lastPos.subtract(this._positions[0]),r=(this._lastTime+n-this._times[0])/1e3,h=i.easeLinearity,l=a.multiplyBy(h/r),u=l.distanceTo([0,0]),c=Math.min(i.inertiaMaxSpeed,u),d=l.multiplyBy(c/u),p=c/(i.inertiaDeceleration*h),_=d.multiplyBy(-p/2).round();_.x&&_.y?(_=e._limitOffset(_,e.options.maxBounds),o.Util.requestAnimFrame(function(){e.panBy(_,{duration:p,easeLinearity:h,noMoveStart:!0})})):e.fire("moveend")}}}),o.Map.addInitHook("addHandler","dragging",o.Map.Drag),o.Map.mergeOptions({doubleClickZoom:!0}),o.Map.DoubleClickZoom=o.Handler.extend({addHooks:function(){this._map.on("dblclick",this._onDoubleClick,this)},removeHooks:function(){this._map.off("dblclick",this._onDoubleClick,this)},_onDoubleClick:function(t){var e=this._map,i=e.getZoom()+(t.originalEvent.shiftKey?-1:1);"center"===e.options.doubleClickZoom?e.setZoom(i):e.setZoomAround(t.containerPoint,i)}}),o.Map.addInitHook("addHandler","doubleClickZoom",o.Map.DoubleClickZoom),o.Map.mergeOptions({scrollWheelZoom:!0}),o.Map.ScrollWheelZoom=o.Handler.extend({addHooks:function(){o.DomEvent.on(this._map._container,"mousewheel",this._onWheelScroll,this),o.DomEvent.on(this._map._container,"MozMousePixelScroll",o.DomEvent.preventDefault),this._delta=0},removeHooks:function(){o.DomEvent.off(this._map._container,"mousewheel",this._onWheelScroll),o.DomEvent.off(this._map._container,"MozMousePixelScroll",o.DomEvent.preventDefault)},_onWheelScroll:function(t){var e=o.DomEvent.getWheelDelta(t);this._delta+=e,this._lastMousePos=this._map.mouseEventToContainerPoint(t),this._startTime||(this._startTime=+new Date);var i=Math.max(40-(+new Date-this._startTime),0);clearTimeout(this._timer),this._timer=setTimeout(o.bind(this._performZoom,this),i),o.DomEvent.preventDefault(t),o.DomEvent.stopPropagation(t)},_performZoom:function(){var t=this._map,e=this._delta,i=t.getZoom();e=e>0?Math.ceil(e):Math.floor(e),e=Math.max(Math.min(e,4),-4),e=t._limitZoom(i+e)-i,this._delta=0,this._startTime=null,e&&("center"===t.options.scrollWheelZoom?t.setZoom(i+e):t.setZoomAround(this._lastMousePos,i+e))}}),o.Map.addInitHook("addHandler","scrollWheelZoom",o.Map.ScrollWheelZoom),o.extend(o.DomEvent,{_touchstart:o.Browser.msPointer?"MSPointerDown":o.Browser.pointer?"pointerdown":"touchstart",_touchend:o.Browser.msPointer?"MSPointerUp":o.Browser.pointer?"pointerup":"touchend",addDoubleTapListener:function(t,i,n){function s(t){var e;if(o.Browser.pointer?(_.push(t.pointerId),e=_.length):e=t.touches.length,!(e>1)){var i=Date.now(),n=i-(r||i);h=t.touches?t.touches[0]:t,l=n>0&&u>=n,r=i}}function a(t){if(o.Browser.pointer){var e=_.indexOf(t.pointerId);if(-1===e)return;_.splice(e,1)}if(l){if(o.Browser.pointer){var n,s={};for(var a in h)n=h[a],s[a]="function"==typeof n?n.bind(h):n;h=s}h.type="dblclick",i(h),r=null}}var r,h,l=!1,u=250,c="_leaflet_",d=this._touchstart,p=this._touchend,_=[];t[c+d+n]=s,t[c+p+n]=a;var m=o.Browser.pointer?e.documentElement:t;return t.addEventListener(d,s,!1),m.addEventListener(p,a,!1),o.Browser.pointer&&m.addEventListener(o.DomEvent.POINTER_CANCEL,a,!1),this},removeDoubleTapListener:function(t,i){var n="_leaflet_";return t.removeEventListener(this._touchstart,t[n+this._touchstart+i],!1),(o.Browser.pointer?e.documentElement:t).removeEventListener(this._touchend,t[n+this._touchend+i],!1),o.Browser.pointer&&e.documentElement.removeEventListener(o.DomEvent.POINTER_CANCEL,t[n+this._touchend+i],!1),this}}),o.extend(o.DomEvent,{POINTER_DOWN:o.Browser.msPointer?"MSPointerDown":"pointerdown",POINTER_MOVE:o.Browser.msPointer?"MSPointerMove":"pointermove",POINTER_UP:o.Browser.msPointer?"MSPointerUp":"pointerup",POINTER_CANCEL:o.Browser.msPointer?"MSPointerCancel":"pointercancel",_pointers:[],_pointerDocumentListener:!1,addPointerListener:function(t,e,i,n){switch(e){case"touchstart":return this.addPointerListenerStart(t,e,i,n);case"touchend":return this.addPointerListenerEnd(t,e,i,n);case"touchmove":return this.addPointerListenerMove(t,e,i,n);default:throw"Unknown touch event type"}},addPointerListenerStart:function(t,i,n,s){var a="_leaflet_",r=this._pointers,h=function(t){o.DomEvent.preventDefault(t); +for(var e=!1,i=0;i1))&&(this._moved||(o.DomUtil.addClass(e._mapPane,"leaflet-touching"),e.fire("movestart").fire("zoomstart"),this._moved=!0),o.Util.cancelAnimFrame(this._animRequest),this._animRequest=o.Util.requestAnimFrame(this._updateOnMove,this,!0,this._map._container),o.DomEvent.preventDefault(t))}},_updateOnMove:function(){var t=this._map,e=this._getScaleOrigin(),i=t.layerPointToLatLng(e),n=t.getScaleZoom(this._scale);t._animateZoom(i,n,this._startCenter,this._scale,this._delta)},_onTouchEnd:function(){if(!this._moved||!this._zooming)return this._zooming=!1,void 0;var t=this._map;this._zooming=!1,o.DomUtil.removeClass(t._mapPane,"leaflet-touching"),o.Util.cancelAnimFrame(this._animRequest),o.DomEvent.off(e,"touchmove",this._onTouchMove).off(e,"touchend",this._onTouchEnd);var i=this._getScaleOrigin(),n=t.layerPointToLatLng(i),s=t.getZoom(),a=t.getScaleZoom(this._scale)-s,r=a>0?Math.ceil(a):Math.floor(a),h=t._limitZoom(s+r),l=t.getZoomScale(h)/this._scale;t._animateZoom(n,h,i,l)},_getScaleOrigin:function(){var t=this._centerOffset.subtract(this._delta).divideBy(this._scale);return this._startCenter.add(t)}}),o.Map.addInitHook("addHandler","touchZoom",o.Map.TouchZoom),o.Map.mergeOptions({tap:!0,tapTolerance:15}),o.Map.Tap=o.Handler.extend({addHooks:function(){o.DomEvent.on(this._map._container,"touchstart",this._onDown,this)},removeHooks:function(){o.DomEvent.off(this._map._container,"touchstart",this._onDown,this)},_onDown:function(t){if(t.touches){if(o.DomEvent.preventDefault(t),this._fireClick=!0,t.touches.length>1)return this._fireClick=!1,clearTimeout(this._holdTimeout),void 0;var i=t.touches[0],n=i.target;this._startPos=this._newPos=new o.Point(i.clientX,i.clientY),n.tagName&&"a"===n.tagName.toLowerCase()&&o.DomUtil.addClass(n,"leaflet-active"),this._holdTimeout=setTimeout(o.bind(function(){this._isTapValid()&&(this._fireClick=!1,this._onUp(),this._simulateEvent("contextmenu",i))},this),1e3),o.DomEvent.on(e,"touchmove",this._onMove,this).on(e,"touchend",this._onUp,this)}},_onUp:function(t){if(clearTimeout(this._holdTimeout),o.DomEvent.off(e,"touchmove",this._onMove,this).off(e,"touchend",this._onUp,this),this._fireClick&&t&&t.changedTouches){var i=t.changedTouches[0],n=i.target;n&&n.tagName&&"a"===n.tagName.toLowerCase()&&o.DomUtil.removeClass(n,"leaflet-active"),this._isTapValid()&&this._simulateEvent("click",i)}},_isTapValid:function(){return this._newPos.distanceTo(this._startPos)<=this._map.options.tapTolerance},_onMove:function(t){var e=t.touches[0];this._newPos=new o.Point(e.clientX,e.clientY)},_simulateEvent:function(i,n){var o=e.createEvent("MouseEvents");o._simulated=!0,n.target._simulatedClick=!0,o.initMouseEvent(i,!0,!0,t,1,n.screenX,n.screenY,n.clientX,n.clientY,!1,!1,!1,!1,0,null),n.target.dispatchEvent(o)}}),o.Browser.touch&&!o.Browser.pointer&&o.Map.addInitHook("addHandler","tap",o.Map.Tap),o.Map.mergeOptions({boxZoom:!0}),o.Map.BoxZoom=o.Handler.extend({initialize:function(t){this._map=t,this._container=t._container,this._pane=t._panes.overlayPane,this._moved=!1},addHooks:function(){o.DomEvent.on(this._container,"mousedown",this._onMouseDown,this)},removeHooks:function(){o.DomEvent.off(this._container,"mousedown",this._onMouseDown),this._moved=!1},moved:function(){return this._moved},_onMouseDown:function(t){return this._moved=!1,!t.shiftKey||1!==t.which&&1!==t.button?!1:(o.DomUtil.disableTextSelection(),o.DomUtil.disableImageDrag(),this._startLayerPoint=this._map.mouseEventToLayerPoint(t),o.DomEvent.on(e,"mousemove",this._onMouseMove,this).on(e,"mouseup",this._onMouseUp,this).on(e,"keydown",this._onKeyDown,this),void 0)},_onMouseMove:function(t){this._moved||(this._box=o.DomUtil.create("div","leaflet-zoom-box",this._pane),o.DomUtil.setPosition(this._box,this._startLayerPoint),this._container.style.cursor="crosshair",this._map.fire("boxzoomstart"));var e=this._startLayerPoint,i=this._box,n=this._map.mouseEventToLayerPoint(t),s=n.subtract(e),a=new o.Point(Math.min(n.x,e.x),Math.min(n.y,e.y));o.DomUtil.setPosition(i,a),this._moved=!0,i.style.width=Math.max(0,Math.abs(s.x)-4)+"px",i.style.height=Math.max(0,Math.abs(s.y)-4)+"px"},_finish:function(){this._moved&&(this._pane.removeChild(this._box),this._container.style.cursor=""),o.DomUtil.enableTextSelection(),o.DomUtil.enableImageDrag(),o.DomEvent.off(e,"mousemove",this._onMouseMove).off(e,"mouseup",this._onMouseUp).off(e,"keydown",this._onKeyDown)},_onMouseUp:function(t){this._finish();var e=this._map,i=e.mouseEventToLayerPoint(t);if(!this._startLayerPoint.equals(i)){var n=new o.LatLngBounds(e.layerPointToLatLng(this._startLayerPoint),e.layerPointToLatLng(i));e.fitBounds(n),e.fire("boxzoomend",{boxZoomBounds:n})}},_onKeyDown:function(t){27===t.keyCode&&this._finish()}}),o.Map.addInitHook("addHandler","boxZoom",o.Map.BoxZoom),o.Map.mergeOptions({keyboard:!0,keyboardPanOffset:80,keyboardZoomOffset:1}),o.Map.Keyboard=o.Handler.extend({keyCodes:{left:[37],right:[39],down:[40],up:[38],zoomIn:[187,107,61,171],zoomOut:[189,109,173]},initialize:function(t){this._map=t,this._setPanOffset(t.options.keyboardPanOffset),this._setZoomOffset(t.options.keyboardZoomOffset)},addHooks:function(){var t=this._map._container;-1===t.tabIndex&&(t.tabIndex="0"),o.DomEvent.on(t,"focus",this._onFocus,this).on(t,"blur",this._onBlur,this).on(t,"mousedown",this._onMouseDown,this),this._map.on("focus",this._addHooks,this).on("blur",this._removeHooks,this)},removeHooks:function(){this._removeHooks();var t=this._map._container;o.DomEvent.off(t,"focus",this._onFocus,this).off(t,"blur",this._onBlur,this).off(t,"mousedown",this._onMouseDown,this),this._map.off("focus",this._addHooks,this).off("blur",this._removeHooks,this)},_onMouseDown:function(){if(!this._focused){var i=e.body,n=e.documentElement,o=i.scrollTop||n.scrollTop,s=i.scrollLeft||n.scrollLeft;this._map._container.focus(),t.scrollTo(s,o)}},_onFocus:function(){this._focused=!0,this._map.fire("focus")},_onBlur:function(){this._focused=!1,this._map.fire("blur")},_setPanOffset:function(t){var e,i,n=this._panKeys={},o=this.keyCodes;for(e=0,i=o.left.length;i>e;e++)n[o.left[e]]=[-1*t,0];for(e=0,i=o.right.length;i>e;e++)n[o.right[e]]=[t,0];for(e=0,i=o.down.length;i>e;e++)n[o.down[e]]=[0,t];for(e=0,i=o.up.length;i>e;e++)n[o.up[e]]=[0,-1*t]},_setZoomOffset:function(t){var e,i,n=this._zoomKeys={},o=this.keyCodes;for(e=0,i=o.zoomIn.length;i>e;e++)n[o.zoomIn[e]]=t;for(e=0,i=o.zoomOut.length;i>e;e++)n[o.zoomOut[e]]=-t},_addHooks:function(){o.DomEvent.on(e,"keydown",this._onKeyDown,this)},_removeHooks:function(){o.DomEvent.off(e,"keydown",this._onKeyDown,this)},_onKeyDown:function(t){var e=t.keyCode,i=this._map;if(e in this._panKeys){if(i._panAnim&&i._panAnim._inProgress)return;i.panBy(this._panKeys[e]),i.options.maxBounds&&i.panInsideBounds(i.options.maxBounds)}else{if(!(e in this._zoomKeys))return;i.setZoom(i.getZoom()+this._zoomKeys[e])}o.DomEvent.stop(t)}}),o.Map.addInitHook("addHandler","keyboard",o.Map.Keyboard),o.Handler.MarkerDrag=o.Handler.extend({initialize:function(t){this._marker=t},addHooks:function(){var t=this._marker._icon;this._draggable||(this._draggable=new o.Draggable(t,t)),this._draggable.on("dragstart",this._onDragStart,this).on("drag",this._onDrag,this).on("dragend",this._onDragEnd,this),this._draggable.enable(),o.DomUtil.addClass(this._marker._icon,"leaflet-marker-draggable")},removeHooks:function(){this._draggable.off("dragstart",this._onDragStart,this).off("drag",this._onDrag,this).off("dragend",this._onDragEnd,this),this._draggable.disable(),o.DomUtil.removeClass(this._marker._icon,"leaflet-marker-draggable")},moved:function(){return this._draggable&&this._draggable._moved},_onDragStart:function(){this._marker.closePopup().fire("movestart").fire("dragstart")},_onDrag:function(){var t=this._marker,e=t._shadow,i=o.DomUtil.getPosition(t._icon),n=t._map.layerPointToLatLng(i);e&&o.DomUtil.setPosition(e,i),t._latlng=n,t.fire("move",{latlng:n}).fire("drag")},_onDragEnd:function(t){this._marker.fire("moveend").fire("dragend",t)}}),o.Control=o.Class.extend({options:{position:"topright"},initialize:function(t){o.setOptions(this,t)},getPosition:function(){return this.options.position},setPosition:function(t){var e=this._map;return e&&e.removeControl(this),this.options.position=t,e&&e.addControl(this),this},getContainer:function(){return this._container},addTo:function(t){this._map=t;var e=this._container=this.onAdd(t),i=this.getPosition(),n=t._controlCorners[i];return o.DomUtil.addClass(e,"leaflet-control"),-1!==i.indexOf("bottom")?n.insertBefore(e,n.firstChild):n.appendChild(e),this},removeFrom:function(t){var e=this.getPosition(),i=t._controlCorners[e];return i.removeChild(this._container),this._map=null,this.onRemove&&this.onRemove(t),this},_refocusOnMap:function(){this._map&&this._map.getContainer().focus()}}),o.control=function(t){return new o.Control(t)},o.Map.include({addControl:function(t){return t.addTo(this),this},removeControl:function(t){return t.removeFrom(this),this},_initControlPos:function(){function t(t,s){var a=i+t+" "+i+s;e[t+s]=o.DomUtil.create("div",a,n)}var e=this._controlCorners={},i="leaflet-",n=this._controlContainer=o.DomUtil.create("div",i+"control-container",this._container);t("top","left"),t("top","right"),t("bottom","left"),t("bottom","right")},_clearControlPos:function(){this._container.removeChild(this._controlContainer)}}),o.Control.Zoom=o.Control.extend({options:{position:"topleft",zoomInText:"+",zoomInTitle:"Zoom in",zoomOutText:"-",zoomOutTitle:"Zoom out"},onAdd:function(t){var e="leaflet-control-zoom",i=o.DomUtil.create("div",e+" leaflet-bar");return this._map=t,this._zoomInButton=this._createButton(this.options.zoomInText,this.options.zoomInTitle,e+"-in",i,this._zoomIn,this),this._zoomOutButton=this._createButton(this.options.zoomOutText,this.options.zoomOutTitle,e+"-out",i,this._zoomOut,this),this._updateDisabled(),t.on("zoomend zoomlevelschange",this._updateDisabled,this),i},onRemove:function(t){t.off("zoomend zoomlevelschange",this._updateDisabled,this)},_zoomIn:function(t){this._map.zoomIn(t.shiftKey?3:1)},_zoomOut:function(t){this._map.zoomOut(t.shiftKey?3:1)},_createButton:function(t,e,i,n,s,a){var r=o.DomUtil.create("a",i,n);r.innerHTML=t,r.href="#",r.title=e;var h=o.DomEvent.stopPropagation;return o.DomEvent.on(r,"click",h).on(r,"mousedown",h).on(r,"dblclick",h).on(r,"click",o.DomEvent.preventDefault).on(r,"click",s,a).on(r,"click",this._refocusOnMap,a),r},_updateDisabled:function(){var t=this._map,e="leaflet-disabled";o.DomUtil.removeClass(this._zoomInButton,e),o.DomUtil.removeClass(this._zoomOutButton,e),t._zoom===t.getMinZoom()&&o.DomUtil.addClass(this._zoomOutButton,e),t._zoom===t.getMaxZoom()&&o.DomUtil.addClass(this._zoomInButton,e)}}),o.Map.mergeOptions({zoomControl:!0}),o.Map.addInitHook(function(){this.options.zoomControl&&(this.zoomControl=new o.Control.Zoom,this.addControl(this.zoomControl))}),o.control.zoom=function(t){return new o.Control.Zoom(t)},o.Control.Attribution=o.Control.extend({options:{position:"bottomright",prefix:'Leaflet'},initialize:function(t){o.setOptions(this,t),this._attributions={}},onAdd:function(t){this._container=o.DomUtil.create("div","leaflet-control-attribution"),o.DomEvent.disableClickPropagation(this._container);for(var e in t._layers)t._layers[e].getAttribution&&this.addAttribution(t._layers[e].getAttribution());return t.on("layeradd",this._onLayerAdd,this).on("layerremove",this._onLayerRemove,this),this._update(),this._container},onRemove:function(t){t.off("layeradd",this._onLayerAdd).off("layerremove",this._onLayerRemove)},setPrefix:function(t){return this.options.prefix=t,this._update(),this},addAttribution:function(t){return t?(this._attributions[t]||(this._attributions[t]=0),this._attributions[t]++,this._update(),this):void 0},removeAttribution:function(t){return t?(this._attributions[t]&&(this._attributions[t]--,this._update()),this):void 0},_update:function(){if(this._map){var t=[];for(var e in this._attributions)this._attributions[e]&&t.push(e);var i=[];this.options.prefix&&i.push(this.options.prefix),t.length&&i.push(t.join(", ")),this._container.innerHTML=i.join(" | ")}},_onLayerAdd:function(t){t.layer.getAttribution&&this.addAttribution(t.layer.getAttribution())},_onLayerRemove:function(t){t.layer.getAttribution&&this.removeAttribution(t.layer.getAttribution())}}),o.Map.mergeOptions({attributionControl:!0}),o.Map.addInitHook(function(){this.options.attributionControl&&(this.attributionControl=(new o.Control.Attribution).addTo(this))}),o.control.attribution=function(t){return new o.Control.Attribution(t)},o.Control.Scale=o.Control.extend({options:{position:"bottomleft",maxWidth:100,metric:!0,imperial:!0,updateWhenIdle:!1},onAdd:function(t){this._map=t;var e="leaflet-control-scale",i=o.DomUtil.create("div",e),n=this.options;return this._addScales(n,e,i),t.on(n.updateWhenIdle?"moveend":"move",this._update,this),t.whenReady(this._update,this),i},onRemove:function(t){t.off(this.options.updateWhenIdle?"moveend":"move",this._update,this)},_addScales:function(t,e,i){t.metric&&(this._mScale=o.DomUtil.create("div",e+"-line",i)),t.imperial&&(this._iScale=o.DomUtil.create("div",e+"-line",i))},_update:function(){var t=this._map.getBounds(),e=t.getCenter().lat,i=6378137*Math.PI*Math.cos(e*Math.PI/180),n=i*(t.getNorthEast().lng-t.getSouthWest().lng)/180,o=this._map.getSize(),s=this.options,a=0;o.x>0&&(a=n*(s.maxWidth/o.x)),this._updateScales(s,a)},_updateScales:function(t,e){t.metric&&e&&this._updateMetric(e),t.imperial&&e&&this._updateImperial(e)},_updateMetric:function(t){var e=this._getRoundNum(t);this._mScale.style.width=this._getScaleWidth(e/t)+"px",this._mScale.innerHTML=1e3>e?e+" m":e/1e3+" km"},_updateImperial:function(t){var e,i,n,o=3.2808399*t,s=this._iScale;o>5280?(e=o/5280,i=this._getRoundNum(e),s.style.width=this._getScaleWidth(i/e)+"px",s.innerHTML=i+" mi"):(n=this._getRoundNum(o),s.style.width=this._getScaleWidth(n/o)+"px",s.innerHTML=n+" ft")},_getScaleWidth:function(t){return Math.round(this.options.maxWidth*t)-10},_getRoundNum:function(t){var e=Math.pow(10,(Math.floor(t)+"").length-1),i=t/e;return i=i>=10?10:i>=5?5:i>=3?3:i>=2?2:1,e*i}}),o.control.scale=function(t){return new o.Control.Scale(t)},o.Control.Layers=o.Control.extend({options:{collapsed:!0,position:"topright",autoZIndex:!0},initialize:function(t,e,i){o.setOptions(this,i),this._layers={},this._lastZIndex=0,this._handlingClick=!1;for(var n in t)this._addLayer(t[n],n);for(n in e)this._addLayer(e[n],n,!0)},onAdd:function(t){return this._initLayout(),this._update(),t.on("layeradd",this._onLayerChange,this).on("layerremove",this._onLayerChange,this),this._container},onRemove:function(t){t.off("layeradd",this._onLayerChange).off("layerremove",this._onLayerChange)},addBaseLayer:function(t,e){return this._addLayer(t,e),this._update(),this},addOverlay:function(t,e){return this._addLayer(t,e,!0),this._update(),this},removeLayer:function(t){var e=o.stamp(t);return delete this._layers[e],this._update(),this},_initLayout:function(){var t="leaflet-control-layers",e=this._container=o.DomUtil.create("div",t);e.setAttribute("aria-haspopup",!0),o.Browser.touch?o.DomEvent.on(e,"click",o.DomEvent.stopPropagation):o.DomEvent.disableClickPropagation(e).disableScrollPropagation(e);var i=this._form=o.DomUtil.create("form",t+"-list");if(this.options.collapsed){o.Browser.android||o.DomEvent.on(e,"mouseover",this._expand,this).on(e,"mouseout",this._collapse,this);var n=this._layersLink=o.DomUtil.create("a",t+"-toggle",e);n.href="#",n.title="Layers",o.Browser.touch?o.DomEvent.on(n,"click",o.DomEvent.stop).on(n,"click",this._expand,this):o.DomEvent.on(n,"focus",this._expand,this),o.DomEvent.on(i,"click",function(){setTimeout(o.bind(this._onInputClick,this),0)},this),this._map.on("click",this._collapse,this)}else this._expand();this._baseLayersList=o.DomUtil.create("div",t+"-base",i),this._separator=o.DomUtil.create("div",t+"-separator",i),this._overlaysList=o.DomUtil.create("div",t+"-overlays",i),e.appendChild(i)},_addLayer:function(t,e,i){var n=o.stamp(t);this._layers[n]={layer:t,name:e,overlay:i},this.options.autoZIndex&&t.setZIndex&&(this._lastZIndex++,t.setZIndex(this._lastZIndex))},_update:function(){if(this._container){this._baseLayersList.innerHTML="",this._overlaysList.innerHTML="";var t,e,i=!1,n=!1;for(t in this._layers)e=this._layers[t],this._addItem(e),n=n||e.overlay,i=i||!e.overlay;this._separator.style.display=n&&i?"":"none"}},_onLayerChange:function(t){var e=this._layers[o.stamp(t.layer)];if(e){this._handlingClick||this._update();var i=e.overlay?"layeradd"===t.type?"overlayadd":"overlayremove":"layeradd"===t.type?"baselayerchange":null;i&&this._map.fire(i,e)}},_createRadioElement:function(t,i){var n='t;t++)e=n[t],i=this._layers[e.layerId],e.checked&&!this._map.hasLayer(i.layer)?this._map.addLayer(i.layer):!e.checked&&this._map.hasLayer(i.layer)&&this._map.removeLayer(i.layer);this._handlingClick=!1,this._refocusOnMap()},_expand:function(){o.DomUtil.addClass(this._container,"leaflet-control-layers-expanded")},_collapse:function(){this._container.className=this._container.className.replace(" leaflet-control-layers-expanded","")}}),o.control.layers=function(t,e,i){return new o.Control.Layers(t,e,i)},o.PosAnimation=o.Class.extend({includes:o.Mixin.Events,run:function(t,e,i,n){this.stop(),this._el=t,this._inProgress=!0,this._newPos=e,this.fire("start"),t.style[o.DomUtil.TRANSITION]="all "+(i||.25)+"s cubic-bezier(0,0,"+(n||.5)+",1)",o.DomEvent.on(t,o.DomUtil.TRANSITION_END,this._onTransitionEnd,this),o.DomUtil.setPosition(t,e),o.Util.falseFn(t.offsetWidth),this._stepTimer=setInterval(o.bind(this._onStep,this),50)},stop:function(){this._inProgress&&(o.DomUtil.setPosition(this._el,this._getPos()),this._onTransitionEnd(),o.Util.falseFn(this._el.offsetWidth))},_onStep:function(){var t=this._getPos();return t?(this._el._leaflet_pos=t,this.fire("step"),void 0):(this._onTransitionEnd(),void 0)},_transformRe:/([-+]?(?:\d*\.)?\d+)\D*, ([-+]?(?:\d*\.)?\d+)\D*\)/,_getPos:function(){var e,i,n,s=this._el,a=t.getComputedStyle(s);if(o.Browser.any3d){if(n=a[o.DomUtil.TRANSFORM].match(this._transformRe),!n)return;e=parseFloat(n[1]),i=parseFloat(n[2])}else e=parseFloat(a.left),i=parseFloat(a.top);return new o.Point(e,i,!0)},_onTransitionEnd:function(){o.DomEvent.off(this._el,o.DomUtil.TRANSITION_END,this._onTransitionEnd,this),this._inProgress&&(this._inProgress=!1,this._el.style[o.DomUtil.TRANSITION]="",this._el._leaflet_pos=this._newPos,clearInterval(this._stepTimer),this.fire("step").fire("end"))}}),o.Map.include({setView:function(t,e,n){if(e=e===i?this._zoom:this._limitZoom(e),t=this._limitCenter(o.latLng(t),e,this.options.maxBounds),n=n||{},this._panAnim&&this._panAnim.stop(),this._loaded&&!n.reset&&n!==!0){n.animate!==i&&(n.zoom=o.extend({animate:n.animate},n.zoom),n.pan=o.extend({animate:n.animate},n.pan));var s=this._zoom!==e?this._tryAnimatedZoom&&this._tryAnimatedZoom(t,e,n.zoom):this._tryAnimatedPan(t,n.pan);if(s)return clearTimeout(this._sizeTimer),this}return this._resetView(t,e),this},panBy:function(t,e){if(t=o.point(t).round(),e=e||{},!t.x&&!t.y)return this;if(this._panAnim||(this._panAnim=new o.PosAnimation,this._panAnim.on({step:this._onPanTransitionStep,end:this._onPanTransitionEnd},this)),e.noMoveStart||this.fire("movestart"),e.animate!==!1){o.DomUtil.addClass(this._mapPane,"leaflet-pan-anim");var i=this._getMapPanePos().subtract(t);this._panAnim.run(this._mapPane,i,e.duration||.25,e.easeLinearity)}else this._rawPanBy(t),this.fire("move").fire("moveend");return this},_onPanTransitionStep:function(){this.fire("move")},_onPanTransitionEnd:function(){o.DomUtil.removeClass(this._mapPane,"leaflet-pan-anim"),this.fire("moveend")},_tryAnimatedPan:function(t,e){var i=this._getCenterOffset(t)._floor();return(e&&e.animate)===!0||this.getSize().contains(i)?(this.panBy(i,e),!0):!1}}),o.PosAnimation=o.DomUtil.TRANSITION?o.PosAnimation:o.PosAnimation.extend({run:function(t,e,i,n){this.stop(),this._el=t,this._inProgress=!0,this._duration=i||.25,this._easeOutPower=1/Math.max(n||.5,.2),this._startPos=o.DomUtil.getPosition(t),this._offset=e.subtract(this._startPos),this._startTime=+new Date,this.fire("start"),this._animate()},stop:function(){this._inProgress&&(this._step(),this._complete())},_animate:function(){this._animId=o.Util.requestAnimFrame(this._animate,this),this._step()},_step:function(){var t=+new Date-this._startTime,e=1e3*this._duration;e>t?this._runFrame(this._easeOut(t/e)):(this._runFrame(1),this._complete())},_runFrame:function(t){var e=this._startPos.add(this._offset.multiplyBy(t));o.DomUtil.setPosition(this._el,e),this.fire("step")},_complete:function(){o.Util.cancelAnimFrame(this._animId),this._inProgress=!1,this.fire("end")},_easeOut:function(t){return 1-Math.pow(1-t,this._easeOutPower)}}),o.Map.mergeOptions({zoomAnimation:!0,zoomAnimationThreshold:4}),o.DomUtil.TRANSITION&&o.Map.addInitHook(function(){this._zoomAnimated=this.options.zoomAnimation&&o.DomUtil.TRANSITION&&o.Browser.any3d&&!o.Browser.android23&&!o.Browser.mobileOpera,this._zoomAnimated&&o.DomEvent.on(this._mapPane,o.DomUtil.TRANSITION_END,this._catchTransitionEnd,this)}),o.Map.include(o.DomUtil.TRANSITION?{_catchTransitionEnd:function(t){this._animatingZoom&&t.propertyName.indexOf("transform")>=0&&this._onZoomTransitionEnd()},_nothingToAnimate:function(){return!this._container.getElementsByClassName("leaflet-zoom-animated").length},_tryAnimatedZoom:function(t,e,i){if(this._animatingZoom)return!0;if(i=i||{},!this._zoomAnimated||i.animate===!1||this._nothingToAnimate()||Math.abs(e-this._zoom)>this.options.zoomAnimationThreshold)return!1;var n=this.getZoomScale(e),o=this._getCenterOffset(t)._divideBy(1-1/n),s=this._getCenterLayerPoint()._add(o);return i.animate===!0||this.getSize().contains(o)?(this.fire("movestart").fire("zoomstart"),this._animateZoom(t,e,s,n,null,!0),!0):!1},_animateZoom:function(t,e,i,n,s,a){this._animatingZoom=!0,o.DomUtil.addClass(this._mapPane,"leaflet-zoom-anim"),this._animateToCenter=t,this._animateToZoom=e,o.Draggable&&(o.Draggable._disabled=!0),this.fire("zoomanim",{center:t,zoom:e,origin:i,scale:n,delta:s,backwards:a})},_onZoomTransitionEnd:function(){this._animatingZoom=!1,o.DomUtil.removeClass(this._mapPane,"leaflet-zoom-anim"),this._resetView(this._animateToCenter,this._animateToZoom,!0,!0),o.Draggable&&(o.Draggable._disabled=!1)}}:{}),o.TileLayer.include({_animateZoom:function(t){this._animating||(this._animating=!0,this._prepareBgBuffer());var e=this._bgBuffer,i=o.DomUtil.TRANSFORM,n=t.delta?o.DomUtil.getTranslateString(t.delta):e.style[i],s=o.DomUtil.getScaleString(t.scale,t.origin);e.style[i]=t.backwards?s+" "+n:n+" "+s},_endZoomAnim:function(){var t=this._tileContainer,e=this._bgBuffer;t.style.visibility="",t.parentNode.appendChild(t),o.Util.falseFn(e.offsetWidth),this._animating=!1},_clearBgBuffer:function(){var t=this._map;!t||t._animatingZoom||t.touchZoom._zooming||(this._bgBuffer.innerHTML="",this._bgBuffer.style[o.DomUtil.TRANSFORM]="")},_prepareBgBuffer:function(){var t=this._tileContainer,e=this._bgBuffer,i=this._getLoadedTilesPercentage(e),n=this._getLoadedTilesPercentage(t);return e&&i>.5&&.5>n?(t.style.visibility="hidden",this._stopLoadingImages(t),void 0):(e.style.visibility="hidden",e.style[o.DomUtil.TRANSFORM]="",this._tileContainer=e,e=this._bgBuffer=t,this._stopLoadingImages(e),clearTimeout(this._clearBgBufferTimer),void 0)},_getLoadedTilesPercentage:function(t){var e,i,n=t.getElementsByTagName("img"),o=0;for(e=0,i=n.length;i>e;e++)n[e].complete&&o++;return o/i},_stopLoadingImages:function(t){var e,i,n,s=Array.prototype.slice.call(t.getElementsByTagName("img"));for(e=0,i=s.length;i>e;e++)n=s[e],n.complete||(n.onload=o.Util.falseFn,n.onerror=o.Util.falseFn,n.src=o.Util.emptyImageUrl,n.parentNode.removeChild(n))}}),o.Map.include({_defaultLocateOptions:{watch:!1,setView:!1,maxZoom:1/0,timeout:1e4,maximumAge:0,enableHighAccuracy:!1},locate:function(t){if(t=this._locateOptions=o.extend(this._defaultLocateOptions,t),!navigator.geolocation)return this._handleGeolocationError({code:0,message:"Geolocation not supported."}),this;var e=o.bind(this._handleGeolocationResponse,this),i=o.bind(this._handleGeolocationError,this);return t.watch?this._locationWatchId=navigator.geolocation.watchPosition(e,i,t):navigator.geolocation.getCurrentPosition(e,i,t),this},stopLocate:function(){return navigator.geolocation&&navigator.geolocation.clearWatch(this._locationWatchId),this._locateOptions&&(this._locateOptions.setView=!1),this},_handleGeolocationError:function(t){var e=t.code,i=t.message||(1===e?"permission denied":2===e?"position unavailable":"timeout");this._locateOptions.setView&&!this._loaded&&this.fitWorld(),this.fire("locationerror",{code:e,message:"Geolocation error: "+i+"."})},_handleGeolocationResponse:function(t){var e=t.coords.latitude,i=t.coords.longitude,n=new o.LatLng(e,i),s=180*t.coords.accuracy/40075017,a=s/Math.cos(o.LatLng.DEG_TO_RAD*e),r=o.latLngBounds([e-s,i-a],[e+s,i+a]),h=this._locateOptions;if(h.setView){var l=Math.min(this.getBoundsZoom(r),h.maxZoom);this.setView(n,l)}var u={latlng:n,bounds:r,timestamp:t.timestamp};for(var c in t.coords)"number"==typeof t.coords[c]&&(u[c]=t.coords[c]);this.fire("locationfound",u)}})}(window,document); \ No newline at end of file diff --git a/main.js b/main.js index 071eb7c7..b704b05e 100644 --- a/main.js +++ b/main.js @@ -1,7 +1,7 @@ // ==UserScript== // @id ingress-intel-total-conversion@jonatkins // @name IITC: Ingress intel map total conversion -// @version 0.16.0.@@DATETIMEVERSION@@ +// @version 0.16.1.@@DATETIMEVERSION@@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ @@ -39,8 +39,11 @@ if(!d) { // page doesn’t have a script tag with player information. if(document.getElementById('header_email')) { // however, we are logged in. - setTimeout('location.reload();', 3*1000); - throw("Page doesn't have player data, but you are logged in. Reloading in 3s."); + // it used to be regularly common to get temporary 'account not enabled' messages from the intel site. + // however, this is no longer common. more common is users getting account suspended/banned - and this + // currently shows the 'not enabled' message. so it's safer to not repeatedly reload in this case +// setTimeout('location.reload();', 3*1000); + throw("Page doesn't have player data, but you are logged in."); } // FIXME: handle nia takedown in progress throw("Couldn't retrieve player data. Are you logged in?"); diff --git a/mobile/AndroidManifest.xml b/mobile/AndroidManifest.xml index 874ec60a..39cb0e92 100644 --- a/mobile/AndroidManifest.xml +++ b/mobile/AndroidManifest.xml @@ -2,8 +2,8 @@ + android:versionCode="62" + android:versionName="0.10.1"> diff --git a/mobile/res/drawable-hdpi/action_about.png b/mobile/res/drawable-hdpi/action_about.png deleted file mode 100644 index 6eaf08ae..00000000 Binary files a/mobile/res/drawable-hdpi/action_about.png and /dev/null differ diff --git a/mobile/res/drawable-hdpi/action_search.png b/mobile/res/drawable-hdpi/action_search.png deleted file mode 100644 index f12e005e..00000000 Binary files a/mobile/res/drawable-hdpi/action_search.png and /dev/null differ diff --git a/mobile/res/drawable-hdpi/action_settings.png b/mobile/res/drawable-hdpi/action_settings.png deleted file mode 100644 index 3e4580e0..00000000 Binary files a/mobile/res/drawable-hdpi/action_settings.png and /dev/null differ diff --git a/mobile/res/drawable-hdpi/alerts_and_states_warning.png b/mobile/res/drawable-hdpi/alerts_and_states_warning.png deleted file mode 100644 index 1fefdd8b..00000000 Binary files a/mobile/res/drawable-hdpi/alerts_and_states_warning.png and /dev/null differ diff --git a/mobile/res/drawable-hdpi/av_full_screen.png b/mobile/res/drawable-hdpi/av_full_screen.png deleted file mode 100644 index 52601b03..00000000 Binary files a/mobile/res/drawable-hdpi/av_full_screen.png and /dev/null differ diff --git a/mobile/res/drawable-hdpi/browser.png b/mobile/res/drawable-hdpi/browser.png deleted file mode 100644 index e154afdb..00000000 Binary files a/mobile/res/drawable-hdpi/browser.png and /dev/null differ diff --git a/mobile/res/drawable-hdpi/collections_view_as_list.png b/mobile/res/drawable-hdpi/collections_view_as_list.png deleted file mode 100644 index e45ea1fd..00000000 Binary files a/mobile/res/drawable-hdpi/collections_view_as_list.png and /dev/null differ diff --git a/mobile/res/drawable-hdpi/content_remove.png b/mobile/res/drawable-hdpi/content_remove.png deleted file mode 100644 index 094eea58..00000000 Binary files a/mobile/res/drawable-hdpi/content_remove.png and /dev/null differ diff --git a/mobile/res/drawable-hdpi/copy.png b/mobile/res/drawable-hdpi/copy.png deleted file mode 100644 index 623b7150..00000000 Binary files a/mobile/res/drawable-hdpi/copy.png and /dev/null differ diff --git a/mobile/res/drawable-hdpi/device_access_location_found.png b/mobile/res/drawable-hdpi/device_access_location_found.png deleted file mode 100644 index d7fae7e9..00000000 Binary files a/mobile/res/drawable-hdpi/device_access_location_found.png and /dev/null differ diff --git a/mobile/res/drawable-hdpi/drawer_shadow.9.png b/mobile/res/drawable-hdpi/drawer_shadow.9.png deleted file mode 100644 index 224cc4ff..00000000 Binary files a/mobile/res/drawable-hdpi/drawer_shadow.9.png and /dev/null differ diff --git a/mobile/res/drawable-hdpi/ic_action_about.png b/mobile/res/drawable-hdpi/ic_action_about.png new file mode 100644 index 00000000..b1f14062 Binary files /dev/null and b/mobile/res/drawable-hdpi/ic_action_about.png differ diff --git a/mobile/res/drawable-hdpi/ic_action_add_to_queue.png b/mobile/res/drawable-hdpi/ic_action_add_to_queue.png new file mode 100644 index 00000000..ecebce71 Binary files /dev/null and b/mobile/res/drawable-hdpi/ic_action_add_to_queue.png differ diff --git a/mobile/res/drawable-hdpi/ic_action_cc_bcc.png b/mobile/res/drawable-hdpi/ic_action_cc_bcc.png new file mode 100644 index 00000000..3c6eb02b Binary files /dev/null and b/mobile/res/drawable-hdpi/ic_action_cc_bcc.png differ diff --git a/mobile/res/drawable-hdpi/ic_action_copy.png b/mobile/res/drawable-hdpi/ic_action_copy.png new file mode 100644 index 00000000..f97df1d5 Binary files /dev/null and b/mobile/res/drawable-hdpi/ic_action_copy.png differ diff --git a/mobile/res/drawable-hdpi/ic_action_data_usage.png b/mobile/res/drawable-hdpi/ic_action_data_usage.png new file mode 100644 index 00000000..f0f83a02 Binary files /dev/null and b/mobile/res/drawable-hdpi/ic_action_data_usage.png differ diff --git a/mobile/res/drawable-hdpi/ic_action_error.png b/mobile/res/drawable-hdpi/ic_action_error.png new file mode 100644 index 00000000..7837289c Binary files /dev/null and b/mobile/res/drawable-hdpi/ic_action_error.png differ diff --git a/mobile/res/drawable-hdpi/ic_action_full_screen.png b/mobile/res/drawable-hdpi/ic_action_full_screen.png new file mode 100644 index 00000000..22f30d31 Binary files /dev/null and b/mobile/res/drawable-hdpi/ic_action_full_screen.png differ diff --git a/mobile/res/drawable-hdpi/ic_action_group.png b/mobile/res/drawable-hdpi/ic_action_group.png new file mode 100644 index 00000000..d043de6c Binary files /dev/null and b/mobile/res/drawable-hdpi/ic_action_group.png differ diff --git a/mobile/res/drawable-hdpi/ic_action_location_found.png b/mobile/res/drawable-hdpi/ic_action_location_found.png new file mode 100644 index 00000000..4748e901 Binary files /dev/null and b/mobile/res/drawable-hdpi/ic_action_location_found.png differ diff --git a/mobile/res/drawable-hdpi/ic_action_map.png b/mobile/res/drawable-hdpi/ic_action_map.png new file mode 100644 index 00000000..945cf8ce Binary files /dev/null and b/mobile/res/drawable-hdpi/ic_action_map.png differ diff --git a/mobile/res/drawable-hdpi/ic_action_new_event.png b/mobile/res/drawable-hdpi/ic_action_new_event.png new file mode 100644 index 00000000..f01b43e4 Binary files /dev/null and b/mobile/res/drawable-hdpi/ic_action_new_event.png differ diff --git a/mobile/res/drawable-hdpi/ic_action_paste.png b/mobile/res/drawable-hdpi/ic_action_paste.png new file mode 100644 index 00000000..b7e1b554 Binary files /dev/null and b/mobile/res/drawable-hdpi/ic_action_paste.png differ diff --git a/mobile/res/drawable-hdpi/ic_action_place.png b/mobile/res/drawable-hdpi/ic_action_place.png new file mode 100644 index 00000000..dba994d8 Binary files /dev/null and b/mobile/res/drawable-hdpi/ic_action_place.png differ diff --git a/mobile/res/drawable-hdpi/ic_action_refresh.png b/mobile/res/drawable-hdpi/ic_action_refresh.png new file mode 100644 index 00000000..00d70792 Binary files /dev/null and b/mobile/res/drawable-hdpi/ic_action_refresh.png differ diff --git a/mobile/res/drawable-hdpi/ic_action_search.png b/mobile/res/drawable-hdpi/ic_action_search.png new file mode 100644 index 00000000..a70393b5 Binary files /dev/null and b/mobile/res/drawable-hdpi/ic_action_search.png differ diff --git a/mobile/res/drawable-hdpi/ic_action_share.png b/mobile/res/drawable-hdpi/ic_action_share.png new file mode 100644 index 00000000..d52b66ab Binary files /dev/null and b/mobile/res/drawable-hdpi/ic_action_share.png differ diff --git a/mobile/res/drawable-hdpi/navigation_refresh.png b/mobile/res/drawable-hdpi/ic_action_star.png similarity index 86% rename from mobile/res/drawable-hdpi/navigation_refresh.png rename to mobile/res/drawable-hdpi/ic_action_star.png index bb9d855f..7c3e1db9 100644 Binary files a/mobile/res/drawable-hdpi/navigation_refresh.png and b/mobile/res/drawable-hdpi/ic_action_star.png differ diff --git a/mobile/res/drawable-hdpi/ic_action_view_as_list.png b/mobile/res/drawable-hdpi/ic_action_view_as_list.png new file mode 100644 index 00000000..07fde4ac Binary files /dev/null and b/mobile/res/drawable-hdpi/ic_action_view_as_list.png differ diff --git a/mobile/res/drawable-hdpi/collections_view_as_list_compact.png b/mobile/res/drawable-hdpi/ic_action_view_as_list_compact.png similarity index 100% rename from mobile/res/drawable-hdpi/collections_view_as_list_compact.png rename to mobile/res/drawable-hdpi/ic_action_view_as_list_compact.png diff --git a/mobile/res/drawable-hdpi/ic_action_warning.png b/mobile/res/drawable-hdpi/ic_action_warning.png new file mode 100644 index 00000000..12f9dd4b Binary files /dev/null and b/mobile/res/drawable-hdpi/ic_action_warning.png differ diff --git a/mobile/res/drawable-hdpi/ic_action_web_site.png b/mobile/res/drawable-hdpi/ic_action_web_site.png new file mode 100644 index 00000000..8c4add42 Binary files /dev/null and b/mobile/res/drawable-hdpi/ic_action_web_site.png differ diff --git a/mobile/res/drawable-hdpi/ic_debug.png b/mobile/res/drawable-hdpi/ic_debug.png deleted file mode 100644 index 8ed186b4..00000000 Binary files a/mobile/res/drawable-hdpi/ic_debug.png and /dev/null differ diff --git a/mobile/res/drawable-hdpi/ic_drawer.png b/mobile/res/drawable-hdpi/ic_drawer.png index ff7b1def..6614ea4f 100644 Binary files a/mobile/res/drawable-hdpi/ic_drawer.png and b/mobile/res/drawable-hdpi/ic_drawer.png differ diff --git a/mobile/res/drawable-hdpi/ic_layer_chooser.png b/mobile/res/drawable-hdpi/ic_layer_chooser.png deleted file mode 100644 index b03e2f34..00000000 Binary files a/mobile/res/drawable-hdpi/ic_layer_chooser.png and /dev/null differ diff --git a/mobile/res/drawable-hdpi/location_map.png b/mobile/res/drawable-hdpi/location_map.png deleted file mode 100644 index e5907072..00000000 Binary files a/mobile/res/drawable-hdpi/location_map.png and /dev/null differ diff --git a/mobile/res/drawable-hdpi/share.png b/mobile/res/drawable-hdpi/share.png deleted file mode 100644 index c329f58d..00000000 Binary files a/mobile/res/drawable-hdpi/share.png and /dev/null differ diff --git a/mobile/res/drawable-hdpi/social_cc_bcc.png b/mobile/res/drawable-hdpi/social_cc_bcc.png deleted file mode 100644 index 8c4f8b31..00000000 Binary files a/mobile/res/drawable-hdpi/social_cc_bcc.png and /dev/null differ diff --git a/mobile/res/drawable-hdpi/social_group.png b/mobile/res/drawable-hdpi/social_group.png deleted file mode 100644 index dbf88a85..00000000 Binary files a/mobile/res/drawable-hdpi/social_group.png and /dev/null differ diff --git a/mobile/res/drawable-mdpi/action_about.png b/mobile/res/drawable-mdpi/action_about.png deleted file mode 100644 index d7b7e698..00000000 Binary files a/mobile/res/drawable-mdpi/action_about.png and /dev/null differ diff --git a/mobile/res/drawable-mdpi/action_search.png b/mobile/res/drawable-mdpi/action_search.png deleted file mode 100644 index 587d9e0b..00000000 Binary files a/mobile/res/drawable-mdpi/action_search.png and /dev/null differ diff --git a/mobile/res/drawable-mdpi/action_settings.png b/mobile/res/drawable-mdpi/action_settings.png deleted file mode 100644 index d3e42edc..00000000 Binary files a/mobile/res/drawable-mdpi/action_settings.png and /dev/null differ diff --git a/mobile/res/drawable-mdpi/alerts_and_states_warning.png b/mobile/res/drawable-mdpi/alerts_and_states_warning.png deleted file mode 100644 index a39f97d4..00000000 Binary files a/mobile/res/drawable-mdpi/alerts_and_states_warning.png and /dev/null differ diff --git a/mobile/res/drawable-mdpi/av_full_screen.png b/mobile/res/drawable-mdpi/av_full_screen.png deleted file mode 100644 index 6fdcd5fc..00000000 Binary files a/mobile/res/drawable-mdpi/av_full_screen.png and /dev/null differ diff --git a/mobile/res/drawable-mdpi/browser.png b/mobile/res/drawable-mdpi/browser.png deleted file mode 100644 index 41b56ec9..00000000 Binary files a/mobile/res/drawable-mdpi/browser.png and /dev/null differ diff --git a/mobile/res/drawable-mdpi/collections_view_as_list.png b/mobile/res/drawable-mdpi/collections_view_as_list.png deleted file mode 100644 index 9c748b0b..00000000 Binary files a/mobile/res/drawable-mdpi/collections_view_as_list.png and /dev/null differ diff --git a/mobile/res/drawable-mdpi/content_remove.png b/mobile/res/drawable-mdpi/content_remove.png deleted file mode 100644 index 3336760d..00000000 Binary files a/mobile/res/drawable-mdpi/content_remove.png and /dev/null differ diff --git a/mobile/res/drawable-mdpi/copy.png b/mobile/res/drawable-mdpi/copy.png deleted file mode 100644 index efb2445f..00000000 Binary files a/mobile/res/drawable-mdpi/copy.png and /dev/null differ diff --git a/mobile/res/drawable-mdpi/device_access_location_found.png b/mobile/res/drawable-mdpi/device_access_location_found.png deleted file mode 100644 index 9d1f4403..00000000 Binary files a/mobile/res/drawable-mdpi/device_access_location_found.png and /dev/null differ diff --git a/mobile/res/drawable-mdpi/drawer_shadow.9.png b/mobile/res/drawable-mdpi/drawer_shadow.9.png deleted file mode 100644 index 3797f99c..00000000 Binary files a/mobile/res/drawable-mdpi/drawer_shadow.9.png and /dev/null differ diff --git a/mobile/res/drawable-mdpi/ic_action_about.png b/mobile/res/drawable-mdpi/ic_action_about.png new file mode 100644 index 00000000..7ede67d8 Binary files /dev/null and b/mobile/res/drawable-mdpi/ic_action_about.png differ diff --git a/mobile/res/drawable-mdpi/ic_action_add_to_queue.png b/mobile/res/drawable-mdpi/ic_action_add_to_queue.png new file mode 100644 index 00000000..1262bcf5 Binary files /dev/null and b/mobile/res/drawable-mdpi/ic_action_add_to_queue.png differ diff --git a/mobile/res/drawable-mdpi/ic_action_cc_bcc.png b/mobile/res/drawable-mdpi/ic_action_cc_bcc.png new file mode 100644 index 00000000..8e6d3ce9 Binary files /dev/null and b/mobile/res/drawable-mdpi/ic_action_cc_bcc.png differ diff --git a/mobile/res/drawable-mdpi/ic_action_copy.png b/mobile/res/drawable-mdpi/ic_action_copy.png new file mode 100644 index 00000000..507b1391 Binary files /dev/null and b/mobile/res/drawable-mdpi/ic_action_copy.png differ diff --git a/mobile/res/drawable-mdpi/ic_action_data_usage.png b/mobile/res/drawable-mdpi/ic_action_data_usage.png new file mode 100644 index 00000000..02ebf1eb Binary files /dev/null and b/mobile/res/drawable-mdpi/ic_action_data_usage.png differ diff --git a/mobile/res/drawable-mdpi/ic_action_error.png b/mobile/res/drawable-mdpi/ic_action_error.png new file mode 100644 index 00000000..57274d77 Binary files /dev/null and b/mobile/res/drawable-mdpi/ic_action_error.png differ diff --git a/mobile/res/drawable-mdpi/ic_action_full_screen.png b/mobile/res/drawable-mdpi/ic_action_full_screen.png new file mode 100644 index 00000000..e4a9ff0a Binary files /dev/null and b/mobile/res/drawable-mdpi/ic_action_full_screen.png differ diff --git a/mobile/res/drawable-mdpi/ic_action_group.png b/mobile/res/drawable-mdpi/ic_action_group.png new file mode 100644 index 00000000..fa3a4399 Binary files /dev/null and b/mobile/res/drawable-mdpi/ic_action_group.png differ diff --git a/mobile/res/drawable-mdpi/ic_action_location_found.png b/mobile/res/drawable-mdpi/ic_action_location_found.png new file mode 100644 index 00000000..9251ee49 Binary files /dev/null and b/mobile/res/drawable-mdpi/ic_action_location_found.png differ diff --git a/mobile/res/drawable-mdpi/ic_action_map.png b/mobile/res/drawable-mdpi/ic_action_map.png new file mode 100644 index 00000000..8ce5f3d5 Binary files /dev/null and b/mobile/res/drawable-mdpi/ic_action_map.png differ diff --git a/mobile/res/drawable-mdpi/ic_action_new_event.png b/mobile/res/drawable-mdpi/ic_action_new_event.png new file mode 100644 index 00000000..784ee03b Binary files /dev/null and b/mobile/res/drawable-mdpi/ic_action_new_event.png differ diff --git a/mobile/res/drawable-mdpi/ic_action_paste.png b/mobile/res/drawable-mdpi/ic_action_paste.png new file mode 100644 index 00000000..8eebda6c Binary files /dev/null and b/mobile/res/drawable-mdpi/ic_action_paste.png differ diff --git a/mobile/res/drawable-mdpi/ic_action_place.png b/mobile/res/drawable-mdpi/ic_action_place.png new file mode 100644 index 00000000..ce055ca6 Binary files /dev/null and b/mobile/res/drawable-mdpi/ic_action_place.png differ diff --git a/mobile/res/drawable-mdpi/ic_action_refresh.png b/mobile/res/drawable-mdpi/ic_action_refresh.png new file mode 100644 index 00000000..c2920a7a Binary files /dev/null and b/mobile/res/drawable-mdpi/ic_action_refresh.png differ diff --git a/mobile/res/drawable-mdpi/ic_action_search.png b/mobile/res/drawable-mdpi/ic_action_search.png new file mode 100644 index 00000000..4edb1ff9 Binary files /dev/null and b/mobile/res/drawable-mdpi/ic_action_search.png differ diff --git a/mobile/res/drawable-mdpi/ic_action_share.png b/mobile/res/drawable-mdpi/ic_action_share.png new file mode 100644 index 00000000..cce0ab97 Binary files /dev/null and b/mobile/res/drawable-mdpi/ic_action_share.png differ diff --git a/mobile/res/drawable-mdpi/navigation_refresh.png b/mobile/res/drawable-mdpi/ic_action_star.png similarity index 89% rename from mobile/res/drawable-mdpi/navigation_refresh.png rename to mobile/res/drawable-mdpi/ic_action_star.png index bd611e8e..c9e12ac2 100644 Binary files a/mobile/res/drawable-mdpi/navigation_refresh.png and b/mobile/res/drawable-mdpi/ic_action_star.png differ diff --git a/mobile/res/drawable-mdpi/ic_action_view_as_list.png b/mobile/res/drawable-mdpi/ic_action_view_as_list.png new file mode 100644 index 00000000..ccb4c7d7 Binary files /dev/null and b/mobile/res/drawable-mdpi/ic_action_view_as_list.png differ diff --git a/mobile/res/drawable-mdpi/collections_view_as_list_compact.png b/mobile/res/drawable-mdpi/ic_action_view_as_list_compact.png similarity index 100% rename from mobile/res/drawable-mdpi/collections_view_as_list_compact.png rename to mobile/res/drawable-mdpi/ic_action_view_as_list_compact.png diff --git a/mobile/res/drawable-mdpi/ic_action_warning.png b/mobile/res/drawable-mdpi/ic_action_warning.png new file mode 100644 index 00000000..9a04694a Binary files /dev/null and b/mobile/res/drawable-mdpi/ic_action_warning.png differ diff --git a/mobile/res/drawable-mdpi/ic_action_web_site.png b/mobile/res/drawable-mdpi/ic_action_web_site.png new file mode 100644 index 00000000..c073fa5e Binary files /dev/null and b/mobile/res/drawable-mdpi/ic_action_web_site.png differ diff --git a/mobile/res/drawable-mdpi/ic_debug.png b/mobile/res/drawable-mdpi/ic_debug.png deleted file mode 100644 index ac20ea13..00000000 Binary files a/mobile/res/drawable-mdpi/ic_debug.png and /dev/null differ diff --git a/mobile/res/drawable-mdpi/ic_drawer.png b/mobile/res/drawable-mdpi/ic_drawer.png index fb681ba2..b05c026c 100644 Binary files a/mobile/res/drawable-mdpi/ic_drawer.png and b/mobile/res/drawable-mdpi/ic_drawer.png differ diff --git a/mobile/res/drawable-mdpi/ic_layer_chooser.png b/mobile/res/drawable-mdpi/ic_layer_chooser.png deleted file mode 100644 index 8ba65bd8..00000000 Binary files a/mobile/res/drawable-mdpi/ic_layer_chooser.png and /dev/null differ diff --git a/mobile/res/drawable-mdpi/location_map.png b/mobile/res/drawable-mdpi/location_map.png deleted file mode 100644 index 21de2011..00000000 Binary files a/mobile/res/drawable-mdpi/location_map.png and /dev/null differ diff --git a/mobile/res/drawable-mdpi/share.png b/mobile/res/drawable-mdpi/share.png deleted file mode 100644 index 056deb57..00000000 Binary files a/mobile/res/drawable-mdpi/share.png and /dev/null differ diff --git a/mobile/res/drawable-mdpi/social_cc_bcc.png b/mobile/res/drawable-mdpi/social_cc_bcc.png deleted file mode 100644 index 9ec127ed..00000000 Binary files a/mobile/res/drawable-mdpi/social_cc_bcc.png and /dev/null differ diff --git a/mobile/res/drawable-mdpi/social_group.png b/mobile/res/drawable-mdpi/social_group.png deleted file mode 100644 index a19796c3..00000000 Binary files a/mobile/res/drawable-mdpi/social_group.png and /dev/null differ diff --git a/mobile/res/drawable-xhdpi/action_about.png b/mobile/res/drawable-xhdpi/action_about.png deleted file mode 100644 index 4ee903f0..00000000 Binary files a/mobile/res/drawable-xhdpi/action_about.png and /dev/null differ diff --git a/mobile/res/drawable-xhdpi/action_search.png b/mobile/res/drawable-xhdpi/action_search.png deleted file mode 100644 index 3549f84d..00000000 Binary files a/mobile/res/drawable-xhdpi/action_search.png and /dev/null differ diff --git a/mobile/res/drawable-xhdpi/action_settings.png b/mobile/res/drawable-xhdpi/action_settings.png deleted file mode 100644 index 09b01483..00000000 Binary files a/mobile/res/drawable-xhdpi/action_settings.png and /dev/null differ diff --git a/mobile/res/drawable-xhdpi/alerts_and_states_warning.png b/mobile/res/drawable-xhdpi/alerts_and_states_warning.png deleted file mode 100644 index 4f11628f..00000000 Binary files a/mobile/res/drawable-xhdpi/alerts_and_states_warning.png and /dev/null differ diff --git a/mobile/res/drawable-xhdpi/av_full_screen.png b/mobile/res/drawable-xhdpi/av_full_screen.png deleted file mode 100644 index 791240fd..00000000 Binary files a/mobile/res/drawable-xhdpi/av_full_screen.png and /dev/null differ diff --git a/mobile/res/drawable-xhdpi/browser.png b/mobile/res/drawable-xhdpi/browser.png deleted file mode 100644 index 9b77be96..00000000 Binary files a/mobile/res/drawable-xhdpi/browser.png and /dev/null differ diff --git a/mobile/res/drawable-xhdpi/collections_view_as_list.png b/mobile/res/drawable-xhdpi/collections_view_as_list.png deleted file mode 100644 index 95708234..00000000 Binary files a/mobile/res/drawable-xhdpi/collections_view_as_list.png and /dev/null differ diff --git a/mobile/res/drawable-xhdpi/content_remove.png b/mobile/res/drawable-xhdpi/content_remove.png deleted file mode 100644 index f391760e..00000000 Binary files a/mobile/res/drawable-xhdpi/content_remove.png and /dev/null differ diff --git a/mobile/res/drawable-xhdpi/copy.png b/mobile/res/drawable-xhdpi/copy.png deleted file mode 100644 index 00bff33c..00000000 Binary files a/mobile/res/drawable-xhdpi/copy.png and /dev/null differ diff --git a/mobile/res/drawable-xhdpi/device_access_location_found.png b/mobile/res/drawable-xhdpi/device_access_location_found.png deleted file mode 100644 index 52ca8ab7..00000000 Binary files a/mobile/res/drawable-xhdpi/device_access_location_found.png and /dev/null differ diff --git a/mobile/res/drawable-xhdpi/drawer_shadow.9.png b/mobile/res/drawable-xhdpi/drawer_shadow.9.png deleted file mode 100644 index fa3d853e..00000000 Binary files a/mobile/res/drawable-xhdpi/drawer_shadow.9.png and /dev/null differ diff --git a/mobile/res/drawable-xhdpi/ic_action_about.png b/mobile/res/drawable-xhdpi/ic_action_about.png new file mode 100644 index 00000000..4536a8d1 Binary files /dev/null and b/mobile/res/drawable-xhdpi/ic_action_about.png differ diff --git a/mobile/res/drawable-xhdpi/ic_action_add_to_queue.png b/mobile/res/drawable-xhdpi/ic_action_add_to_queue.png new file mode 100644 index 00000000..8190ee04 Binary files /dev/null and b/mobile/res/drawable-xhdpi/ic_action_add_to_queue.png differ diff --git a/mobile/res/drawable-xhdpi/ic_action_cc_bcc.png b/mobile/res/drawable-xhdpi/ic_action_cc_bcc.png new file mode 100644 index 00000000..124ddcb3 Binary files /dev/null and b/mobile/res/drawable-xhdpi/ic_action_cc_bcc.png differ diff --git a/mobile/res/drawable-xhdpi/ic_action_copy.png b/mobile/res/drawable-xhdpi/ic_action_copy.png new file mode 100644 index 00000000..4aa5778e Binary files /dev/null and b/mobile/res/drawable-xhdpi/ic_action_copy.png differ diff --git a/mobile/res/drawable-xhdpi/ic_action_data_usage.png b/mobile/res/drawable-xhdpi/ic_action_data_usage.png new file mode 100644 index 00000000..487f4f82 Binary files /dev/null and b/mobile/res/drawable-xhdpi/ic_action_data_usage.png differ diff --git a/mobile/res/drawable-xhdpi/ic_action_error.png b/mobile/res/drawable-xhdpi/ic_action_error.png new file mode 100644 index 00000000..0933154a Binary files /dev/null and b/mobile/res/drawable-xhdpi/ic_action_error.png differ diff --git a/mobile/res/drawable-xhdpi/ic_action_full_screen.png b/mobile/res/drawable-xhdpi/ic_action_full_screen.png new file mode 100644 index 00000000..2c1df53b Binary files /dev/null and b/mobile/res/drawable-xhdpi/ic_action_full_screen.png differ diff --git a/mobile/res/drawable-xhdpi/ic_action_group.png b/mobile/res/drawable-xhdpi/ic_action_group.png new file mode 100644 index 00000000..7a6efaf6 Binary files /dev/null and b/mobile/res/drawable-xhdpi/ic_action_group.png differ diff --git a/mobile/res/drawable-xhdpi/ic_action_location_found.png b/mobile/res/drawable-xhdpi/ic_action_location_found.png new file mode 100644 index 00000000..f5031892 Binary files /dev/null and b/mobile/res/drawable-xhdpi/ic_action_location_found.png differ diff --git a/mobile/res/drawable-xhdpi/ic_action_map.png b/mobile/res/drawable-xhdpi/ic_action_map.png new file mode 100644 index 00000000..537c5a49 Binary files /dev/null and b/mobile/res/drawable-xhdpi/ic_action_map.png differ diff --git a/mobile/res/drawable-xhdpi/ic_action_new_event.png b/mobile/res/drawable-xhdpi/ic_action_new_event.png new file mode 100644 index 00000000..ed693e51 Binary files /dev/null and b/mobile/res/drawable-xhdpi/ic_action_new_event.png differ diff --git a/mobile/res/drawable-xhdpi/ic_action_paste.png b/mobile/res/drawable-xhdpi/ic_action_paste.png new file mode 100644 index 00000000..56551c4b Binary files /dev/null and b/mobile/res/drawable-xhdpi/ic_action_paste.png differ diff --git a/mobile/res/drawable-xhdpi/ic_action_place.png b/mobile/res/drawable-xhdpi/ic_action_place.png new file mode 100644 index 00000000..49adf813 Binary files /dev/null and b/mobile/res/drawable-xhdpi/ic_action_place.png differ diff --git a/mobile/res/drawable-xhdpi/ic_action_refresh.png b/mobile/res/drawable-xhdpi/ic_action_refresh.png new file mode 100644 index 00000000..6aa33d59 Binary files /dev/null and b/mobile/res/drawable-xhdpi/ic_action_refresh.png differ diff --git a/mobile/res/drawable-xhdpi/ic_action_search.png b/mobile/res/drawable-xhdpi/ic_action_search.png new file mode 100644 index 00000000..19658e4a Binary files /dev/null and b/mobile/res/drawable-xhdpi/ic_action_search.png differ diff --git a/mobile/res/drawable-xhdpi/ic_action_share.png b/mobile/res/drawable-xhdpi/ic_action_share.png new file mode 100644 index 00000000..40771e48 Binary files /dev/null and b/mobile/res/drawable-xhdpi/ic_action_share.png differ diff --git a/mobile/res/drawable-xhdpi/navigation_refresh.png b/mobile/res/drawable-xhdpi/ic_action_star.png similarity index 84% rename from mobile/res/drawable-xhdpi/navigation_refresh.png rename to mobile/res/drawable-xhdpi/ic_action_star.png index a7fdc0df..e3291481 100644 Binary files a/mobile/res/drawable-xhdpi/navigation_refresh.png and b/mobile/res/drawable-xhdpi/ic_action_star.png differ diff --git a/mobile/res/drawable-xhdpi/ic_action_view_as_list.png b/mobile/res/drawable-xhdpi/ic_action_view_as_list.png new file mode 100644 index 00000000..45a3fc70 Binary files /dev/null and b/mobile/res/drawable-xhdpi/ic_action_view_as_list.png differ diff --git a/mobile/res/drawable-xhdpi/collections_view_as_list_compact.png b/mobile/res/drawable-xhdpi/ic_action_view_as_list_compact.png similarity index 100% rename from mobile/res/drawable-xhdpi/collections_view_as_list_compact.png rename to mobile/res/drawable-xhdpi/ic_action_view_as_list_compact.png diff --git a/mobile/res/drawable-xhdpi/ic_action_warning.png b/mobile/res/drawable-xhdpi/ic_action_warning.png new file mode 100644 index 00000000..5cd44b97 Binary files /dev/null and b/mobile/res/drawable-xhdpi/ic_action_warning.png differ diff --git a/mobile/res/drawable-xhdpi/ic_action_web_site.png b/mobile/res/drawable-xhdpi/ic_action_web_site.png new file mode 100644 index 00000000..2d759def Binary files /dev/null and b/mobile/res/drawable-xhdpi/ic_action_web_site.png differ diff --git a/mobile/res/drawable-xhdpi/ic_debug.png b/mobile/res/drawable-xhdpi/ic_debug.png deleted file mode 100644 index aeb96b06..00000000 Binary files a/mobile/res/drawable-xhdpi/ic_debug.png and /dev/null differ diff --git a/mobile/res/drawable-xhdpi/ic_drawer.png b/mobile/res/drawable-xhdpi/ic_drawer.png index b9bc3d70..bcf49dd7 100644 Binary files a/mobile/res/drawable-xhdpi/ic_drawer.png and b/mobile/res/drawable-xhdpi/ic_drawer.png differ diff --git a/mobile/res/drawable-xhdpi/ic_layer_chooser.png b/mobile/res/drawable-xhdpi/ic_layer_chooser.png deleted file mode 100644 index 46089e5b..00000000 Binary files a/mobile/res/drawable-xhdpi/ic_layer_chooser.png and /dev/null differ diff --git a/mobile/res/drawable-xhdpi/location_map.png b/mobile/res/drawable-xhdpi/location_map.png deleted file mode 100644 index f5ce90a3..00000000 Binary files a/mobile/res/drawable-xhdpi/location_map.png and /dev/null differ diff --git a/mobile/res/drawable-xhdpi/share.png b/mobile/res/drawable-xhdpi/share.png deleted file mode 100644 index 15549b04..00000000 Binary files a/mobile/res/drawable-xhdpi/share.png and /dev/null differ diff --git a/mobile/res/drawable-xhdpi/social_cc_bcc.png b/mobile/res/drawable-xhdpi/social_cc_bcc.png deleted file mode 100644 index 4153807e..00000000 Binary files a/mobile/res/drawable-xhdpi/social_cc_bcc.png and /dev/null differ diff --git a/mobile/res/drawable-xhdpi/social_group.png b/mobile/res/drawable-xhdpi/social_group.png deleted file mode 100644 index 32d24d2c..00000000 Binary files a/mobile/res/drawable-xhdpi/social_group.png and /dev/null differ diff --git a/mobile/res/drawable-xxhdpi/ic_action_about.png b/mobile/res/drawable-xxhdpi/ic_action_about.png new file mode 100644 index 00000000..f3db0887 Binary files /dev/null and b/mobile/res/drawable-xxhdpi/ic_action_about.png differ diff --git a/mobile/res/drawable-xxhdpi/ic_action_add_to_queue.png b/mobile/res/drawable-xxhdpi/ic_action_add_to_queue.png new file mode 100644 index 00000000..c30aade6 Binary files /dev/null and b/mobile/res/drawable-xxhdpi/ic_action_add_to_queue.png differ diff --git a/mobile/res/drawable-xxhdpi/ic_action_cc_bcc.png b/mobile/res/drawable-xxhdpi/ic_action_cc_bcc.png new file mode 100644 index 00000000..b66fd656 Binary files /dev/null and b/mobile/res/drawable-xxhdpi/ic_action_cc_bcc.png differ diff --git a/mobile/res/drawable-xxhdpi/ic_action_copy.png b/mobile/res/drawable-xxhdpi/ic_action_copy.png new file mode 100644 index 00000000..a381cdc3 Binary files /dev/null and b/mobile/res/drawable-xxhdpi/ic_action_copy.png differ diff --git a/mobile/res/drawable-xxhdpi/ic_action_data_usage.png b/mobile/res/drawable-xxhdpi/ic_action_data_usage.png new file mode 100644 index 00000000..76631a4d Binary files /dev/null and b/mobile/res/drawable-xxhdpi/ic_action_data_usage.png differ diff --git a/mobile/res/drawable-xxhdpi/ic_action_error.png b/mobile/res/drawable-xxhdpi/ic_action_error.png new file mode 100644 index 00000000..b8a6aaad Binary files /dev/null and b/mobile/res/drawable-xxhdpi/ic_action_error.png differ diff --git a/mobile/res/drawable-xxhdpi/ic_action_full_screen.png b/mobile/res/drawable-xxhdpi/ic_action_full_screen.png new file mode 100644 index 00000000..e8dff1e4 Binary files /dev/null and b/mobile/res/drawable-xxhdpi/ic_action_full_screen.png differ diff --git a/mobile/res/drawable-xxhdpi/ic_action_group.png b/mobile/res/drawable-xxhdpi/ic_action_group.png new file mode 100644 index 00000000..9289b1c8 Binary files /dev/null and b/mobile/res/drawable-xxhdpi/ic_action_group.png differ diff --git a/mobile/res/drawable-xxhdpi/ic_action_location_found.png b/mobile/res/drawable-xxhdpi/ic_action_location_found.png new file mode 100644 index 00000000..e5179540 Binary files /dev/null and b/mobile/res/drawable-xxhdpi/ic_action_location_found.png differ diff --git a/mobile/res/drawable-xxhdpi/ic_action_map.png b/mobile/res/drawable-xxhdpi/ic_action_map.png new file mode 100644 index 00000000..ed72ce91 Binary files /dev/null and b/mobile/res/drawable-xxhdpi/ic_action_map.png differ diff --git a/mobile/res/drawable-xxhdpi/ic_action_new_event.png b/mobile/res/drawable-xxhdpi/ic_action_new_event.png new file mode 100644 index 00000000..9d1b2e74 Binary files /dev/null and b/mobile/res/drawable-xxhdpi/ic_action_new_event.png differ diff --git a/mobile/res/drawable-xxhdpi/ic_action_paste.png b/mobile/res/drawable-xxhdpi/ic_action_paste.png new file mode 100644 index 00000000..cb7682cc Binary files /dev/null and b/mobile/res/drawable-xxhdpi/ic_action_paste.png differ diff --git a/mobile/res/drawable-xxhdpi/ic_action_place.png b/mobile/res/drawable-xxhdpi/ic_action_place.png new file mode 100644 index 00000000..25623c77 Binary files /dev/null and b/mobile/res/drawable-xxhdpi/ic_action_place.png differ diff --git a/mobile/res/drawable-xxhdpi/ic_action_refresh.png b/mobile/res/drawable-xxhdpi/ic_action_refresh.png new file mode 100644 index 00000000..145c9df4 Binary files /dev/null and b/mobile/res/drawable-xxhdpi/ic_action_refresh.png differ diff --git a/mobile/res/drawable-xxhdpi/ic_action_search.png b/mobile/res/drawable-xxhdpi/ic_action_search.png new file mode 100644 index 00000000..a1086388 Binary files /dev/null and b/mobile/res/drawable-xxhdpi/ic_action_search.png differ diff --git a/mobile/res/drawable-xxhdpi/ic_action_share.png b/mobile/res/drawable-xxhdpi/ic_action_share.png new file mode 100644 index 00000000..22ed428f Binary files /dev/null and b/mobile/res/drawable-xxhdpi/ic_action_share.png differ diff --git a/mobile/res/drawable-xxhdpi/ic_action_star.png b/mobile/res/drawable-xxhdpi/ic_action_star.png new file mode 100644 index 00000000..f1e51a75 Binary files /dev/null and b/mobile/res/drawable-xxhdpi/ic_action_star.png differ diff --git a/mobile/res/drawable-xxhdpi/ic_action_view_as_list.png b/mobile/res/drawable-xxhdpi/ic_action_view_as_list.png new file mode 100644 index 00000000..46004164 Binary files /dev/null and b/mobile/res/drawable-xxhdpi/ic_action_view_as_list.png differ diff --git a/mobile/res/drawable-xxhdpi/ic_action_view_as_list_compact.png b/mobile/res/drawable-xxhdpi/ic_action_view_as_list_compact.png new file mode 100644 index 00000000..d04f2c3e Binary files /dev/null and b/mobile/res/drawable-xxhdpi/ic_action_view_as_list_compact.png differ diff --git a/mobile/res/drawable-xxhdpi/ic_action_warning.png b/mobile/res/drawable-xxhdpi/ic_action_warning.png new file mode 100644 index 00000000..b0ad5b2d Binary files /dev/null and b/mobile/res/drawable-xxhdpi/ic_action_warning.png differ diff --git a/mobile/res/drawable-xxhdpi/ic_action_web_site.png b/mobile/res/drawable-xxhdpi/ic_action_web_site.png new file mode 100644 index 00000000..e24eed75 Binary files /dev/null and b/mobile/res/drawable-xxhdpi/ic_action_web_site.png differ diff --git a/mobile/res/drawable-xxhdpi/ic_drawer.png b/mobile/res/drawable-xxhdpi/ic_drawer.png new file mode 100644 index 00000000..f7e3b307 Binary files /dev/null and b/mobile/res/drawable-xxhdpi/ic_drawer.png differ diff --git a/mobile/res/layout/dialog_notice.xml b/mobile/res/layout/dialog_notice.xml new file mode 100644 index 00000000..ab75cd69 --- /dev/null +++ b/mobile/res/layout/dialog_notice.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/mobile/res/menu/main.xml b/mobile/res/menu/main.xml index 941cd9bc..63790b3f 100644 --- a/mobile/res/menu/main.xml +++ b/mobile/res/menu/main.xml @@ -1,38 +1,38 @@ - - + + - \ No newline at end of file + diff --git a/mobile/res/values/strings.xml b/mobile/res/values/strings.xml index 1babb023..8d1ed63c 100644 --- a/mobile/res/values/strings.xml +++ b/mobile/res/values/strings.xml @@ -56,18 +56,26 @@ PERFORMANCE OF THIS SOFTWARE. ]]> - -
+ + How to use IITCm:

• Navigation: swipe from the left edge of your screen (or click the app icon) to evoke the Navigation Drawer. Click the app icon again to return to the map.

• Layers/Highlights: swipe from the right edge of your screen (or click the layer-chooser icon in the ActionBar) - to evoke the Layer Drawer]]> + to evoke the Layer Drawer

+ • You can add official plugins in the settings

+ • For external plugins please have a look at the FAQ]]>

• tap and hold a portal for a second
• tap on the left half of the status bar]]>
+ +
+ Some plugins (e.g. portals list and bookmarks) now appear in the navigation drawer for quick access.
+ They won\'t appear in the info pane any more.

+ Swipe from the left edge of your screen (or click the app icon) to seem them.]]> +
UI Misc @@ -140,10 +148,11 @@ Search Locations Address could not be opened Copied to clipboard… + Do not show again - Map + Locate Share - Browser + Intel Highlighter Base Layer diff --git a/mobile/smartphone.css b/mobile/smartphone.css index bec0a5e8..27d34ad7 100644 --- a/mobile/smartphone.css +++ b/mobile/smartphone.css @@ -1,5 +1,4 @@ body { - background: #000; color: #fff; } @@ -62,6 +61,20 @@ body { -webkit-box-sizing: border-box; } +#mobileinfo .resonator.north:before { + content: ""; + background-color: red; + border-radius: 100%; + display: block; + height: 6px; + width: 6px; + left: 50%; + top: -3px; + margin-left: -3px; + position: absolute; + z-index: -1; +} + #mobileinfo .filllevel { position: absolute; bottom: 0; @@ -81,7 +94,7 @@ body { } #sidebar, #chatcontrols, #chat, #chatinput { - background: #0B3351 !important; + background: transparent !important; } .leaflet-top .leaflet-control { @@ -198,20 +211,19 @@ body { .linkdetails aside { padding: 5px; margin-top: 3px; - margin-botton: 3px; - border: 2px outset #0e3d4e; + margin-bottom: 3px; + border: 2px outset #20A8B1; } #toolbox > a { padding: 5px; margin-top: 3px; - margin-botton: 3px; - border: 2px outset #0e3d4e; + margin-bottom: 3px; + border: 2px outset #20A8B1; } #portaldetails .close { padding: 4px; - border: 1px outset #0e3d4e; + border: 1px outset #20A8B1; margin-top: 2px; - background: #0e3d4e; } diff --git a/mobile/src/com/cradle/iitc_mobile/IITC_JSInterface.java b/mobile/src/com/cradle/iitc_mobile/IITC_JSInterface.java index 0222fbe9..93372fd1 100644 --- a/mobile/src/com/cradle/iitc_mobile/IITC_JSInterface.java +++ b/mobile/src/com/cradle/iitc_mobile/IITC_JSInterface.java @@ -13,8 +13,6 @@ import android.widget.Toast; import com.cradle.iitc_mobile.IITC_NavigationHelper.Pane; import com.cradle.iitc_mobile.share.ShareActivity; -import java.util.Locale; - // provide communication between IITC script and android app public class IITC_JSInterface { // context of main activity @@ -96,7 +94,7 @@ public class IITC_JSInterface { public void run() { Pane pane; try { - pane = Pane.valueOf(id.toUpperCase(Locale.getDefault())); + pane = mIitc.getNavigationHelper().getPane(id); } catch (IllegalArgumentException e) { pane = Pane.MAP; } @@ -170,4 +168,25 @@ public class IITC_JSInterface { } }); } + + @JavascriptInterface + public void addPane(final String name, final String label, final String icon) { + mIitc.runOnUiThread(new Runnable() { + @Override + public void run() { + mIitc.getNavigationHelper().addPane(name, label, icon); + } + }); + } + + // some plugins may have no specific icons...add a default icon + @JavascriptInterface + public void addPane(final String name, final String label) { + mIitc.runOnUiThread(new Runnable() { + @Override + public void run() { + mIitc.getNavigationHelper().addPane(name, label, "ic_action_new_event"); + } + }); + } } diff --git a/mobile/src/com/cradle/iitc_mobile/IITC_MapSettings.java b/mobile/src/com/cradle/iitc_mobile/IITC_MapSettings.java index 1e06f9e1..687aff13 100644 --- a/mobile/src/com/cradle/iitc_mobile/IITC_MapSettings.java +++ b/mobile/src/com/cradle/iitc_mobile/IITC_MapSettings.java @@ -12,7 +12,6 @@ import android.widget.ArrayAdapter; import android.widget.CheckedTextView; import android.widget.ListView; import android.widget.Spinner; -import android.widget.TextView; import org.json.JSONArray; import org.json.JSONException; diff --git a/mobile/src/com/cradle/iitc_mobile/IITC_Mobile.java b/mobile/src/com/cradle/iitc_mobile/IITC_Mobile.java index 92bcc447..668d4310 100644 --- a/mobile/src/com/cradle/iitc_mobile/IITC_Mobile.java +++ b/mobile/src/com/cradle/iitc_mobile/IITC_Mobile.java @@ -35,7 +35,6 @@ import com.cradle.iitc_mobile.IITC_NavigationHelper.Pane; import java.io.File; import java.io.IOException; import java.net.URISyntaxException; -import java.util.Locale; import java.util.Stack; public class IITC_Mobile extends Activity implements OnSharedPreferenceChangeListener, LocationListener { @@ -288,8 +287,8 @@ public class IITC_Mobile extends Activity implements OnSharedPreferenceChangeLis } @Override - protected void onResume() { - super.onResume(); + protected void onStart() { + super.onStart(); // enough idle...let's do some work Log.d("iitcm", "resuming...reset idleTimer"); @@ -313,6 +312,20 @@ public class IITC_Mobile extends Activity implements OnSharedPreferenceChangeLis } } + @Override + protected void onResume() { + mIitcWebView.resumeTimers(); + mIitcWebView.onResume(); + super.onResume(); + } + + @Override + protected void onPause() { + mIitcWebView.pauseTimers(); + mIitcWebView.onPause(); + super.onPause(); + } + @Override protected void onStop() { Log.d("iitcm", "stopping iitcm"); @@ -325,6 +338,12 @@ public class IITC_Mobile extends Activity implements OnSharedPreferenceChangeLis super.onStop(); } + @Override + protected void onDestroy() { + unregisterReceiver(mBroadcastReceiver); + super.onDestroy(); + } + @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); @@ -370,6 +389,7 @@ public class IITC_Mobile extends Activity implements OnSharedPreferenceChangeLis // Pop last item from backstack and pretend the relevant menu item was clicked if (!mBackStack.isEmpty()) { backStackPop(); + mBackButtonPressed = true; return; } @@ -405,15 +425,16 @@ public class IITC_Mobile extends Activity implements OnSharedPreferenceChangeLis // map pane is top-lvl. clear stack. if (pane == Pane.MAP) mBackStack.clear(); - else mBackStack.push(mCurrentPane); + // don't push current pane to backstack if this method was called via back button + else if (!mBackButtonPressed) mBackStack.push(mCurrentPane); + mBackButtonPressed = false; mCurrentPane = pane; mNavigationHelper.switchTo(pane); } public void switchToPane(Pane pane) { - String name = pane.name().toLowerCase(Locale.getDefault()); - mIitcWebView.loadUrl("javascript: window.show('" + name + "');"); + mIitcWebView.loadUrl("javascript: window.show('" + pane.name + "');"); } @Override diff --git a/mobile/src/com/cradle/iitc_mobile/IITC_NavigationHelper.java b/mobile/src/com/cradle/iitc_mobile/IITC_NavigationHelper.java index 0d15cc85..62254373 100644 --- a/mobile/src/com/cradle/iitc_mobile/IITC_NavigationHelper.java +++ b/mobile/src/com/cradle/iitc_mobile/IITC_NavigationHelper.java @@ -6,18 +6,21 @@ import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.DialogInterface.OnDismissListener; import android.content.SharedPreferences; +import android.content.res.Resources; import android.os.Bundle; import android.os.Handler; import android.preference.PreferenceManager; import android.support.v4.app.ActionBarDrawerToggle; import android.support.v4.widget.DrawerLayout; import android.text.Html; +import android.text.method.LinkMovementMethod; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; +import android.widget.CheckBox; import android.widget.ListView; import android.widget.TextView; @@ -34,71 +37,9 @@ public class IITC_NavigationHelper extends ActionBarDrawerToggle implements OnIt // Makes the icon/title clickable // getActionBar().setHomeButtonEnabled(enabled); - private class NavigationAdapter extends ArrayAdapter { - public NavigationAdapter() { - super(mIitc, R.layout.list_item_selectable); - - add(Pane.MAP); - add(Pane.INFO); - add(Pane.FULL); - add(Pane.COMPACT); - add(Pane.PUBLIC); - add(Pane.FACTION); - - if (mPrefs.getBoolean("pref_advanced_menu", false)) { - add(Pane.DEBUG); - } - } - - @Override - public View getView(int position, View convertView, ViewGroup parent) { - TextView view = (TextView) super.getView(position, convertView, parent); - Pane item = getItem(position); - if (item == Pane.MAP) { - view.setText("Map"); - } else { - view.setText(getPaneTitle(item)); - } - - int icon = 0; - switch (item) { - case MAP: - icon = R.drawable.location_map; - break; - case INFO: - icon = R.drawable.action_about; - break; - case FULL: - icon = R.drawable.collections_view_as_list; - break; - case COMPACT: - icon = R.drawable.collections_view_as_list_compact; - break; - case PUBLIC: - icon = R.drawable.social_group; - break; - case FACTION: - icon = R.drawable.social_cc_bcc; - break; - case DEBUG: - icon = R.drawable.ic_debug; - break; - } - - if (icon != 0) { - view.setCompoundDrawablesWithIntrinsicBounds(icon, 0, 0, 0); - } - - return view; - } - } - - public static enum Pane { - COMPACT, DEBUG, FACTION, FULL, INFO, MAP, PUBLIC - } - - public static final int NOTICE_DRAWERS = 1 << 0; + public static final int NOTICE_HOWTO = 1 << 0; public static final int NOTICE_INFO = 1 << 1; + public static final int NOTICE_PANES = 1 << 2; // next one would be 1<<2; (this results in 1,2,4,8,...) private final IITC_Mobile mIitc; @@ -113,6 +54,7 @@ public class IITC_NavigationHelper extends ActionBarDrawerToggle implements OnIt private boolean mIsLoading; private Pane mPane = Pane.MAP; private String mHighlighter = null; + private int mDialogs = 0; public IITC_NavigationHelper(IITC_Mobile activity, ActionBar bar) { super(activity, (DrawerLayout) activity.findViewById(R.id.drawer_layout), @@ -136,32 +78,34 @@ public class IITC_NavigationHelper extends ActionBarDrawerToggle implements OnIt onPrefChanged(); // also calls updateActionBar() - showNotice(NOTICE_DRAWERS); + showNotice(NOTICE_HOWTO); } private void showNotice(final int which) { - if ((mPrefs.getInt("pref_messages", 0) & which) != 0) { - return; - } + if ((mPrefs.getInt("pref_messages", 0) & which) != 0 || (mDialogs & which) != 0) return; - String text; + int text; switch (which) { - case NOTICE_DRAWERS: - text = mIitc.getText(R.string.notice_drawers).toString(); + case NOTICE_HOWTO: + text = R.string.notice_how_to; break; case NOTICE_INFO: - text = mIitc.getText(R.string.notice_info).toString(); + text = R.string.notice_info; + break; + case NOTICE_PANES: + text = R.string.notice_panes; break; default: return; } - TextView message = new TextView(mIitc); - message.setPadding(20, 20, 20, 20); - message.setText(Html.fromHtml(text)); + final View content = mIitc.getLayoutInflater().inflate(R.layout.dialog_notice, null); + TextView message = (TextView) content.findViewById(R.id.tv_notice); + message.setText(Html.fromHtml(mIitc.getString(text))); + message.setMovementMethod(LinkMovementMethod.getInstance()); AlertDialog dialog = new AlertDialog.Builder(mIitc) - .setView(message) + .setView(content) .setCancelable(true) .setPositiveButton(android.R.string.ok, new OnClickListener() { @Override @@ -173,22 +117,29 @@ public class IITC_NavigationHelper extends ActionBarDrawerToggle implements OnIt dialog.setOnDismissListener(new OnDismissListener() { @Override public void onDismiss(DialogInterface dialog) { - int value = mPrefs.getInt("pref_messages", 0); - value |= which; + mDialogs &= ~which; + if (((CheckBox) content.findViewById(R.id.cb_do_not_show_again)).isChecked()) { + int value = mPrefs.getInt("pref_messages", 0); + value |= which; - mPrefs - .edit() - .putInt("pref_messages", value) - .commit(); + mPrefs + .edit() + .putInt("pref_messages", value) + .commit(); + } } }); + + mDialogs |= which; dialog.show(); } - private void updateActionBar() { + private void updateViews() { int position = mNavigationAdapter.getPosition(mPane); if (position >= 0 && position < mNavigationAdapter.getCount()) { mDrawerLeft.setItemChecked(position, true); + } else { + mDrawerLeft.setItemChecked(mDrawerLeft.getCheckedItemPosition(), false); } if (mDesktopMode) { @@ -216,10 +167,10 @@ public class IITC_NavigationHelper extends ActionBarDrawerToggle implements OnIt } } - if (mDrawerLayout.isDrawerOpen(mDrawerLeft)) { + if (mDrawerLayout.isDrawerOpen(mDrawerLeft) || mPane == Pane.MAP) { mActionBar.setTitle(mIitc.getString(R.string.app_name)); } else { - mActionBar.setTitle(getPaneTitle(mPane)); + mActionBar.setTitle(mPane.label); } } @@ -231,27 +182,37 @@ public class IITC_NavigationHelper extends ActionBarDrawerToggle implements OnIt } } + public void addPane(String name, String label, String icon) { + showNotice(NOTICE_PANES); + + Resources res = mIitc.getResources(); + String packageName = res.getResourcePackageName(R.string.app_name); + /* + * since the package name is overridden in test builds + * we can't use context.getPackageName() to get the package name + * because the resources were processed before the package name was finally updated. + * so we have to retrieve the package name of another resource with Resources.getResourcePackageName() + * see http://www.piwai.info/renaming-android-manifest-package/ + */ + int resId = mIitc.getResources().getIdentifier(icon, "drawable", packageName); + mNavigationAdapter.add(new Pane(name, label, resId)); + } + public void closeDrawers() { mDrawerLayout.closeDrawers(); } - public String getPaneTitle(Pane pane) { - switch (pane) { - case INFO: - return "Info"; - case FULL: - return "Full"; - case COMPACT: - return "Compact"; - case PUBLIC: - return "Public"; - case FACTION: - return "Faction"; - case DEBUG: - return "Debug"; - default: - return mIitc.getString(R.string.app_name); + public Pane getPane(String id) { + for (int i = 0; i < mNavigationAdapter.getCount(); i++) { + Pane pane = mNavigationAdapter.getItem(i); + if (pane.name.equals(id)) + return pane; } + throw new IllegalArgumentException("Unknown pane: " + id); + } + + public void hideActionBar() { + mActionBar.hide(); } public boolean isDrawerOpened() { @@ -268,7 +229,7 @@ public class IITC_NavigationHelper extends ActionBarDrawerToggle implements OnIt @Override public void run() { mIitc.invalidateOptionsMenu(); - updateActionBar(); + updateViews(); } }, 200); } @@ -278,7 +239,7 @@ public class IITC_NavigationHelper extends ActionBarDrawerToggle implements OnIt super.onDrawerOpened(drawerView); mIitc.getWebView().onWindowFocusChanged(false); mIitc.invalidateOptionsMenu(); - updateActionBar(); + updateViews(); mDrawerLayout.closeDrawer(drawerView.equals(mDrawerLeft) ? mDrawerRight : mDrawerLeft); } @@ -310,7 +271,7 @@ public class IITC_NavigationHelper extends ActionBarDrawerToggle implements OnIt public void onPrefChanged() { mDesktopMode = mPrefs.getBoolean("pref_force_desktop", false); - updateActionBar(); + updateViews(); } public void openRightDrawer() { @@ -321,37 +282,100 @@ public class IITC_NavigationHelper extends ActionBarDrawerToggle implements OnIt public void reset() { mPane = Pane.MAP; - updateActionBar(); + mNavigationAdapter.reset(); + updateViews(); } public void setDebugMode(boolean enabled) { - mNavigationAdapter.remove(Pane.DEBUG); // avoid duplicates - if (enabled) { - mNavigationAdapter.add(Pane.DEBUG); - } + mNavigationAdapter.reset(); } public void setHighlighter(String name) { mHighlighter = name; - updateActionBar(); + updateViews(); } public void setLoadingState(boolean isLoading) { mIsLoading = isLoading; - updateActionBar(); - } - - public void switchTo(Pane pane) { - mPane = pane; - - updateActionBar(); + updateViews(); } public void showActionBar() { mActionBar.show(); } - public void hideActionBar() { - mActionBar.hide(); + public void switchTo(Pane pane) { + mPane = pane; + + updateViews(); + } + + private class NavigationAdapter extends ArrayAdapter { + public NavigationAdapter() { + super(mIitc, R.layout.list_item_selectable); + + reset(); + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + TextView view = (TextView) super.getView(position, convertView, parent); + Pane item = getItem(position); + view.setText(item.label); + + if (item.icon != 0) { + view.setCompoundDrawablesWithIntrinsicBounds(item.icon, 0, 0, 0); + } + + return view; + } + + public void reset() { + clear(); + + add(Pane.INFO); + add(Pane.FULL); + add(Pane.COMPACT); + add(Pane.PUBLIC); + add(Pane.FACTION); + + if (mPrefs.getBoolean("pref_advanced_menu", false)) { + add(Pane.DEBUG); + } + } + } + + public static class Pane { + public static final Pane COMPACT = new Pane("compact", "Compact", R.drawable.ic_action_view_as_list_compact); + public static final Pane DEBUG = new Pane("debug", "Debug", R.drawable.ic_action_error); + public static final Pane FACTION = new Pane("faction", "Faction", R.drawable.ic_action_cc_bcc); + public static final Pane FULL = new Pane("full", "Full", R.drawable.ic_action_view_as_list); + public static final Pane INFO = new Pane("info", "Info", R.drawable.ic_action_about); + public static final Pane MAP = new Pane("map", "Map", R.drawable.ic_action_map); + public static final Pane PUBLIC = new Pane("public", "Public", R.drawable.ic_action_group); + + private int icon; + public String label; + public String name; + + public Pane(String name, String label, int icon) { + this.name = name; + this.label = label; + this.icon = icon; + } + + @Override + public boolean equals(Object o) { + if (o == null) return false; + if (o.getClass() != getClass()) return false; + + Pane pane = (Pane) o; + return name.equals(pane.name); + } + + @Override + public int hashCode() { + return name.hashCode(); + } } } diff --git a/mobile/src/com/cradle/iitc_mobile/IITC_WebView.java b/mobile/src/com/cradle/iitc_mobile/IITC_WebView.java index c0c0fccf..f00cad8d 100644 --- a/mobile/src/com/cradle/iitc_mobile/IITC_WebView.java +++ b/mobile/src/com/cradle/iitc_mobile/IITC_WebView.java @@ -71,7 +71,15 @@ public class IITC_WebView extends WebView { @Override public void run() { if (isInFullscreen() && (getFullscreenStatus() & (FS_NAVBAR)) != 0) { - setSystemUiVisibility(SYSTEM_UI_FLAG_HIDE_NAVIGATION); + int systemUiVisibility = SYSTEM_UI_FLAG_HIDE_NAVIGATION; + // in immersive mode the user can interact with the app while the navbar is hidden + // this mode is available since KitKat + // you can leave this mode by swiping down from the top of the screen. this does only work + // when the app is in total-fullscreen mode + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && (mFullscreenStatus & FS_SYSBAR) != 0) { + systemUiVisibility |= SYSTEM_UI_FLAG_IMMERSIVE; + } + setSystemUiVisibility(systemUiVisibility); } } }; @@ -165,12 +173,7 @@ public class IITC_WebView extends WebView { public void loadJS(String js) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { - evaluateJavascript(js, new ValueCallback() { - @Override - public void onReceiveValue(String value) { - // maybe we want to add stuff here - } - }); + evaluateJavascript(js, null); } else { // if in edit text mode, don't load javascript otherwise the keyboard closes. HitTestResult testResult = getHitTestResult(); @@ -190,20 +193,22 @@ public class IITC_WebView extends WebView { @Override public boolean onTouchEvent(MotionEvent event) { getHandler().removeCallbacks(mNavHider); - getHandler().postDelayed(mNavHider, 2000); + getHandler().postDelayed(mNavHider, 3000); return super.onTouchEvent(event); } @Override public void setSystemUiVisibility(int visibility) { - getHandler().postDelayed(mNavHider, 2000); + if ((visibility & SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0) { + getHandler().postDelayed(mNavHider, 3000); + } super.setSystemUiVisibility(visibility); } @Override public void onWindowFocusChanged(boolean hasWindowFocus) { if (hasWindowFocus) { - getHandler().postDelayed(mNavHider, 2000); + getHandler().postDelayed(mNavHider, 3000); } else { getHandler().removeCallbacks(mNavHider); } @@ -225,7 +230,7 @@ public class IITC_WebView extends WebView { attrs.flags |= WindowManager.LayoutParams.FLAG_FULLSCREEN; } if ((mFullscreenStatus & FS_NAVBAR) != 0) { - setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION); + getHandler().post(mNavHider); } if ((mFullscreenStatus & FS_STATUSBAR) != 0) { loadUrl("javascript: $('#updatestatus').hide();"); diff --git a/mobile/src/com/cradle/iitc_mobile/fragments/MainSettings.java b/mobile/src/com/cradle/iitc_mobile/fragments/MainSettings.java index 142ae22e..cbcee155 100644 --- a/mobile/src/com/cradle/iitc_mobile/fragments/MainSettings.java +++ b/mobile/src/com/cradle/iitc_mobile/fragments/MainSettings.java @@ -77,7 +77,7 @@ public class MainSettings extends PreferenceFragment { final Dialog dialog = preferenceScreen.getDialog(); if (dialog != null) { - dialog.getActionBar().setDisplayHomeAsUpEnabled(true); + if (dialog.getActionBar() != null) dialog.getActionBar().setDisplayHomeAsUpEnabled(true); View homeBtn = dialog.findViewById(android.R.id.home); diff --git a/mobile/src/com/cradle/iitc_mobile/share/IntentComparator.java b/mobile/src/com/cradle/iitc_mobile/share/IntentComparator.java index 436488e4..b01ab72d 100644 --- a/mobile/src/com/cradle/iitc_mobile/share/IntentComparator.java +++ b/mobile/src/com/cradle/iitc_mobile/share/IntentComparator.java @@ -124,6 +124,13 @@ public class IntentComparator implements Comparator { public int compare(ResolveInfo lhs, ResolveInfo rhs) { int order; + // we might be merging multiple intents, so there could be more than one default + if (lhs.isDefault && !rhs.isDefault) + return -1; + if (rhs.isDefault && !lhs.isDefault) + return 1; + + // Show more frequently used items in top Integer lCount = mIntentMap.get(new Component(lhs)); Integer rCount = mIntentMap.get(new Component(rhs)); @@ -133,8 +140,15 @@ public class IntentComparator implements Comparator { if (lCount > rCount) return -1; if (lCount < rCount) return 1; - order = lhs.loadLabel(mPackageManager).toString() - .compareTo(rhs.loadLabel(mPackageManager).toString()); + // don't known how these are set (or if they can be set at all), but it sounds promising... + if (lhs.preferredOrder != rhs.preferredOrder) + return rhs.preferredOrder - lhs.preferredOrder; + if (lhs.priority != rhs.priority) + return rhs.priority - lhs.priority; + + // still no order. fall back to alphabetical order + order = lhs.loadLabel(mPackageManager).toString().compareTo( + rhs.loadLabel(mPackageManager).toString()); if (order != 0) return order; if (lhs.nonLocalizedLabel != null && rhs.nonLocalizedLabel != null) { diff --git a/mobile/src/com/cradle/iitc_mobile/share/IntentListView.java b/mobile/src/com/cradle/iitc_mobile/share/IntentListView.java index fdec0b86..a0af6dcc 100644 --- a/mobile/src/com/cradle/iitc_mobile/share/IntentListView.java +++ b/mobile/src/com/cradle/iitc_mobile/share/IntentListView.java @@ -9,6 +9,7 @@ import android.content.pm.PackageManager; import android.content.pm.ResolveInfo; import android.graphics.drawable.Drawable; import android.util.AttributeSet; +import android.util.DisplayMetrics; import android.util.Pair; import android.view.LayoutInflater; import android.view.View; @@ -37,6 +38,10 @@ public class IntentListView extends ListView { } private class IntentAdapter extends ArrayAdapter { + + // actually the mdpi pixel size is 48, but this looks ugly...so scale icons down for listView + private static final int MDPI_PX = 36; + private IntentAdapter() { super(IntentListView.this.getContext(), android.R.layout.simple_list_item_1); } @@ -48,11 +53,19 @@ public class IntentListView extends ListView { ActivityInfo info = getItem(position).activityInfo; CharSequence label = info.loadLabel(mPackageManager); + + // get icon and scale it manually to ensure that all have the same size Drawable icon = info.loadIcon(mPackageManager); + DisplayMetrics dm = new DisplayMetrics(); + ((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(dm); + float densityScale = dm.density; + float scaledWidth = MDPI_PX * densityScale; + float scaledHeight = MDPI_PX * densityScale; + icon.setBounds(0,0,Math.round(scaledWidth),Math.round(scaledHeight)); view.setText(label); view.setCompoundDrawablePadding((int) getResources().getDimension(R.dimen.icon_margin)); - view.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null); + view.setCompoundDrawables(icon, null, null, null); return view; } @@ -174,17 +187,16 @@ public class IntentListView extends ListView { ActivityInfo activity = resolveInfo.activityInfo; ComponentName activityId = new ComponentName(activity.packageName, activity.name); + // ResolveInfo.isDefault usually means "The target would like to be considered a default action that the + // user can perform on this data." It is set by the package manager, but we overwrite it to store + // whether this app is the default for the given intent + resolveInfo.isDefault = resolveInfo.activityInfo.name.equals(defaultTarget.activityInfo.name) + && resolveInfo.activityInfo.packageName.equals(defaultTarget.activityInfo.packageName); + if (!mActivities.containsKey(activityId)) { mActivities.put(activityId, intent); - // move default Intent to top - if (resolveInfo.activityInfo.packageName.equals(defaultTarget.activityInfo.packageName) - && resolveInfo.activityInfo.name.equals(defaultTarget.activityInfo.name)) { - allActivities.add(0, resolveInfo); - } else { - allActivities.add(resolveInfo); - } + allActivities.add(resolveInfo); } - } } diff --git a/mobile/src/com/cradle/iitc_mobile/share/ShareActivity.java b/mobile/src/com/cradle/iitc_mobile/share/ShareActivity.java index 3ba21fa2..fe10d5c3 100644 --- a/mobile/src/com/cradle/iitc_mobile/share/ShareActivity.java +++ b/mobile/src/com/cradle/iitc_mobile/share/ShareActivity.java @@ -81,10 +81,10 @@ public class ShareActivity extends FragmentActivity implements ActionBar.TabList String geoUri = "geo:" + mLl; Intent geoIntent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse(geoUri)); intents.add(geoIntent); - addTab(intents, R.string.tab_map, R.drawable.location_map); + addTab(intents, R.string.tab_map, R.drawable.ic_action_place); Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(getUrl())); - addTab(intent, R.string.tab_browser, R.drawable.browser); + addTab(intent, R.string.tab_browser, R.drawable.ic_action_web_site); } private void setupShareIntent(String str) { @@ -93,7 +93,7 @@ public class ShareActivity extends FragmentActivity implements ActionBar.TabList intent.setType("text/plain"); intent.putExtra(Intent.EXTRA_TEXT, str); intent.putExtra(Intent.EXTRA_SUBJECT, mTitle); - addTab(intent, R.string.tab_share, R.drawable.share); + addTab(intent, R.string.tab_share, R.drawable.ic_action_share); } @Override @@ -116,6 +116,7 @@ public class ShareActivity extends FragmentActivity implements ActionBar.TabList mZoom = intent.getIntExtra("zoom", 0); mIsPortal = intent.getBooleanExtra("isPortal", false); + actionBar.setTitle(mTitle); setupIntents(); } else { mTitle = getString(R.string.app_name); diff --git a/plugins/add-kml.user.js b/plugins/add-kml.user.js index 0ff7d41b..1ba8191e 100644 --- a/plugins/add-kml.user.js +++ b/plugins/add-kml.user.js @@ -6,7 +6,7 @@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Allows users to overlay their own KML / GPX files on top of IITC +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Allow users to overlay their own KML / GPX files on top of IITC. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* diff --git a/plugins/basemap-bing.user.js b/plugins/basemap-bing.user.js index a9b8478c..52944b49 100644 --- a/plugins/basemap-bing.user.js +++ b/plugins/basemap-bing.user.js @@ -2,11 +2,11 @@ // @id iitc-plugin-bing-maps // @name IITC plugin: Bing maps // @category Map Tiles -// @version 0.1.1.@@DATETIMEVERSION@@ +// @version 0.1.2.@@DATETIMEVERSION@@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Add the maps.bing.com map layers ( +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Add the maps.bing.com map layers. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* @@ -23,7 +23,7 @@ window.plugin.mapBing = function() {}; window.plugin.mapBing.setupBingLeaflet = function() { @@INCLUDERAW:external/Bing.js@@ } - + window.plugin.mapBing.setup = function() { window.plugin.mapBing.setupBingLeaflet(); @@ -37,12 +37,35 @@ window.plugin.mapBing.setup = function() { 'AerialWithLabels': "Aerial with labels", }; + // bing maps has an annual usage limit, which will likely be hit in 6 months at this time. + // it seems that the usage is counted on initialising the L.BingLayer, when the metadata is retrieved. + // so, we'll create some dummy layers and add those to the map, then, the first time a layer is added, + // create the L.BingLayer. This will eliminate all usage for users who install but don't use the map, + // and only create usage for the map layers actually selected in use + + var bingMapContainers = []; + for (type in bingTypes) { var name = bingTypes[type]; - var bingMap = new L.BingLayer(bingApiKey, {type: type, maxZoom:20}); - layerChooser.addBaseLayer(bingMap, 'Bing '+name); + + bingMapContainers[type] = new L.LayerGroup(); + layerChooser.addBaseLayer(bingMapContainers[type], 'Bing '+name); } + // now a leaflet event to catch base layer changes and create a L.BingLayer when needed + map.on('baselayerchange', function(e) { + for (type in bingMapContainers) { + if (e.layer == bingMapContainers[type]) { + if (bingMapContainers[type].getLayers().length == 0) { + // dummy layer group is empty - create the bing layer + console.log('basemap-bing: creating '+type+' layer'); + var bingMap = new L.BingLayer (bingApiKey, {type: type, maxZoom:20}); + bingMapContainers[type].addLayer(bingMap); + } + } + } + }); + }; var setup = window.plugin.mapBing.setup; diff --git a/plugins/basemap-cloudmade.user.js b/plugins/basemap-cloudmade.user.js index 34b584be..20027d7d 100644 --- a/plugins/basemap-cloudmade.user.js +++ b/plugins/basemap-cloudmade.user.js @@ -11,7 +11,7 @@ // optional: browse their map styles, add/modify any you like to the cmStyles list // You take your own responsibility for any API key you register and use. Please read -// any relevant terms and conditions. At the time of writing, Cloudmade offer a reasonable +// any relevant terms and conditions. At the time of writing, Cloudmade offers a reasonable // number of free requests, which should be more than enough for personal use. You could // probably share a key with a group of people without issues, but it is your responsibility // to remain within any terms and usage limits. diff --git a/plugins/basemap-gmaps-gray.user.js b/plugins/basemap-gmaps-gray.user.js index 28f31b00..73c73fdf 100644 --- a/plugins/basemap-gmaps-gray.user.js +++ b/plugins/basemap-gmaps-gray.user.js @@ -6,7 +6,7 @@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Add a simplified gray Version of Google map tiles as an optional layer +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Add a simplified gray Version of Google map tiles as an optional layer. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* diff --git a/plugins/basemap-mapquest-open-aerial.user.js b/plugins/basemap-mapquest-open-aerial.user.js index 30d1fe06..776b93d7 100644 --- a/plugins/basemap-mapquest-open-aerial.user.js +++ b/plugins/basemap-mapquest-open-aerial.user.js @@ -6,7 +6,7 @@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Adds the MapQuest Open Aerial satellite view tiles as a map layer. High detail in the US (lower 48) only +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Add the MapQuest Open Aerial satellite view tiles as a map layer. High detail in the US (lower 48) only. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* diff --git a/plugins/basemap-nokia-ovi.user.js b/plugins/basemap-nokia-ovi.user.js index e345d921..fe0a1bc2 100644 --- a/plugins/basemap-nokia-ovi.user.js +++ b/plugins/basemap-nokia-ovi.user.js @@ -6,7 +6,7 @@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Add various map layers from Nokia OVI Maps +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Add various map layers from Nokia OVI Maps. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* diff --git a/plugins/basemap-opencyclemap.user.js b/plugins/basemap-opencyclemap.user.js index 5d5964e0..5ba1175b 100644 --- a/plugins/basemap-opencyclemap.user.js +++ b/plugins/basemap-opencyclemap.user.js @@ -6,7 +6,7 @@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Add the OpenCycleMap.org map tiles as an optional layer +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Add the OpenCycleMap.org map tiles as an optional layer. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* diff --git a/plugins/basemap-openstreetmap.user.js b/plugins/basemap-openstreetmap.user.js index 3a1ebc59..a0661e2f 100644 --- a/plugins/basemap-openstreetmap.user.js +++ b/plugins/basemap-openstreetmap.user.js @@ -6,7 +6,7 @@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Add the native OpenStreetMap.org map tiles as an optional layer +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Add the native OpenStreetMap.org map tiles as an optional layer. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* diff --git a/plugins/basemap-stamen.user.js b/plugins/basemap-stamen.user.js index 80e6a3c6..a9520f84 100644 --- a/plugins/basemap-stamen.user.js +++ b/plugins/basemap-stamen.user.js @@ -6,7 +6,7 @@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Adds the 'Toner' and 'Watercolor' map layers from maps.stamen.com +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Add the 'Toner' and 'Watercolor' map layers from maps.stamen.com. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* diff --git a/plugins/bookmarks-by-zaso.user.js b/plugins/bookmarks-by-zaso.user.js index 89d4e6ed..339233ef 100644 --- a/plugins/bookmarks-by-zaso.user.js +++ b/plugins/bookmarks-by-zaso.user.js @@ -6,7 +6,7 @@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Save your favorite Maps and Portals and move the intelmap with a click. Now sync. +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Save your favorite Maps and Portals and move the intel map with a click. Now with sync. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* @@ -169,6 +169,13 @@ window.plugin.bookmarks.saveStorageBox(); } + window.plugin.bookmarks.onPaneChanged = function(pane) { + if(pane == "plugin-bookmarks") + $('#bookmarksBox').css("display", ""); + else + $('#bookmarksBox').css("display", "none"); + } + // Switch list (maps/portals) window.plugin.bookmarks.switchPageBkmrksBox = function(elem, page) { window.plugin.bookmarks.statusBox.page = page; @@ -938,8 +945,13 @@ $("#bookmarksBox #bookmarksMin , #bookmarksBox ul li, #bookmarksBox ul li a, #bookmarksBox ul li a span, #bookmarksBox h5, #bookmarksBox .addForm a").disableSelection(); $('#bookmarksBox').css({'top':window.plugin.bookmarks.statusBox.pos.x, 'left':window.plugin.bookmarks.statusBox.pos.y}); }else{ - $('#portaldetails').before(window.plugin.bookmarks.htmlBoxTrigger + window.plugin.bookmarks.htmlBkmrksBox); + $('body').append(window.plugin.bookmarks.htmlBkmrksBox); + $('#bookmarksBox').css("display", "none").addClass("mobile"); + if(window.useAndroidPanes()) + android.addPane("plugin-bookmarks", "Bookmarks", "ic_action_star"); + window.addHook('paneChanged', window.plugin.bookmarks.onPaneChanged); + // Remove the star window.addHook('portalSelected', function(data) { if(data.selectedPortalGuid === null) { diff --git a/plugins/bookmarks-css.css b/plugins/bookmarks-css.css index 2fca0d09..9c160667 100644 --- a/plugins/bookmarks-css.css +++ b/plugins/bookmarks-css.css @@ -358,139 +358,131 @@ /********************************************** MOBILE **********************************************/ -#sidebar #bookmarksBox{ - position:static !important; - width:auto !important; - margin:0 !important; +#bookmarksBox.mobile{ + position:absolute !important; + width: 100% !important; + height: 100% !important; + top: 0 !important; + left: 0 !important; + margin: 0 !important; + padding: 0 !important; + border: 0 !important; + background: transparent !important;; } -#sidebar #bkmrksTrigger, -#sidebar #bookmarksBox .bookmarkList ul, -#sidebar #bookmarksBox .bookmarkList ul li, -#sidebar #bookmarksBox .bookmarkList.current, -#sidebar #bookmarksBox .bookmarkList li.bookmarkFolder.open ul{ +#bookmarksBox.mobile .bookmarkList ul, +#bookmarksBox.mobile .bookmarkList ul li, +#bookmarksBox.mobile .bookmarkList.current, +#bookmarksBox.mobile .bookmarkList li.bookmarkFolder.open ul{ width:100% !important; display:block !important; } -#sidebar #bookmarksBox *{ +#bookmarksBox.mobile *{ box-shadow:none !important; border-width:0 !important; } -#sidebar #bookmarksBox #topBar{ +#bookmarksBox.mobile #topBar{ display:none !important; } -#sidebar #bookmarksBox #bookmarksTypeBar h5{ +#bookmarksBox.mobile #bookmarksTypeBar h5{ cursor:pointer; text-align:center; float:left; width:50%; padding:7px 0; } -#sidebar #bookmarksBox #bookmarksTypeBar h5.current{ +#bookmarksBox.mobile #bookmarksTypeBar h5.current{ cursor:default; color:#fff; } -#sidebar #bookmarksBox #bookmarksTypeBar, -#sidebar #bookmarksBox .bookmarkList .addForm{ +#bookmarksBox.mobile #bookmarksTypeBar, +#bookmarksBox.mobile .bookmarkList .addForm{ border-bottom:1px solid #20a8b1 !important; } -#sidebar #bookmarksBox .bookmarkList ul li ul li.bkmrk, -#sidebar #bookmarksBox .bookmarkList li.bookmarkFolder .folderLabel{ +#bookmarksBox.mobile .bookmarkList ul li ul li.bkmrk, +#bookmarksBox.mobile .bookmarkList li.bookmarkFolder .folderLabel{ height:36px !important; clear:both; } -#sidebar #bookmarksBox .bookmarkList li.bookmarkFolder .folderLabel a, -#sidebar #bookmarksBox .bookmarkList ul li ul li.bkmrk a{ +#bookmarksBox.mobile .bookmarkList li.bookmarkFolder .folderLabel a, +#bookmarksBox.mobile .bookmarkList ul li ul li.bkmrk a{ background:none; padding:7px 0; height:auto; box-shadow:inset 0 1px 0 #20a8b1 !important; } -#sidebar #bookmarksBox .bookmarkList li.bookmarkFolder a.bookmarksRemoveFrom, -#sidebar #bookmarksBox .bookmarkList li.bkmrk a.bookmarksRemoveFrom{ +#bookmarksBox.mobile .bookmarkList li.bookmarkFolder a.bookmarksRemoveFrom, +#bookmarksBox.mobile .bookmarkList li.bkmrk a.bookmarksRemoveFrom{ box-shadow:inset 0 1px 0 #20a8b1,inset -1px 0 0 #20a8b1 !important; width:15%; background:none !important; } -#sidebar #bookmarksBox .bookmarkList li.bookmarkFolder a.bookmarksAnchor, -#sidebar #bookmarksBox .bookmarkList li.bkmrk a.bookmarksLink{ +#bookmarksBox.mobile .bookmarkList li.bookmarkFolder a.bookmarksAnchor, +#bookmarksBox.mobile .bookmarkList li.bkmrk a.bookmarksLink{ text-indent:10px; width:85%; height:21px; overflow:hidden; } -#sidebar #bookmarksBox .bookmarkList ul li.bookmarkFolder ul{ +#bookmarksBox.mobile .bookmarkList ul li.bookmarkFolder ul{ margin-left:0 !important; } -#sidebar #bookmarksBox .bookmarkList > ul{ +#bookmarksBox.mobile .bookmarkList > ul{ border-bottom:1px solid #20a8b1 !important; border-right:1px solid #20a8b1 !important; } -#sidebar #bookmarksBox .bookmarkList .bookmarkFolder.othersBookmarks ul{ +#bookmarksBox.mobile .bookmarkList .bookmarkFolder.othersBookmarks ul{ border-top:5px solid #20a8b1 !important; } -#sidebar #bookmarksBox .bookmarkList li.bookmarkFolder, -#sidebar #bookmarksBox .bookmarkList li.bkmrk{ +#bookmarksBox.mobile .bookmarkList li.bookmarkFolder, +#bookmarksBox.mobile .bookmarkList li.bkmrk{ box-shadow:inset 0 1px 0 #20a8b1, 1px 0 0 #20a8b1, -1px 1px 0 #20a8b1 !important; } -#sidebar #bookmarksBox .bookmarkList > ul{ +#bookmarksBox.mobile .bookmarkList > ul{ max-height:none; width:85% !important; } -#sidebar #bookmarksBox .bookmarkList li.bookmarkFolder .folderLabel{ +#bookmarksBox.mobile .bookmarkList li.bookmarkFolder .folderLabel{ box-shadow:0 1px 0 #20a8b1 !important; } -#sidebar #bookmarksBox .bookmarkList ul li.bookmarkFolder ul{ +#bookmarksBox.mobile .bookmarkList ul li.bookmarkFolder ul{ width:85% !important; margin-left:15% !important; } -#sidebar #bookmarksBox .bookmarkList ul li.bookmarkFolder.othersBookmarks ul{ +#bookmarksBox.mobile .bookmarkList ul li.bookmarkFolder.othersBookmarks ul{ width:100% !important; margin-left:0% !important; } -#sidebar #bkmrksTrigger{ - position:static; - width:auto; - margin:0; - height:auto; - background:none; - text-indent:0; - padding:11px 0 9px; - margin-bottom:5px; -} -#sidebar #bkmrksTrigger.open{ - margin-bottom:0; -} -#sidebar #bookmarksBox{ +#bookmarksBox.mobile{ margin-bottom:5px !important; } -#sidebar #bookmarksBox #bookmarksTypeBar{ +#bookmarksBox.mobile #bookmarksTypeBar{ height:auto; } -#sidebar #bookmarksBox .addForm, -#sidebar #bookmarksBox .addForm *{ +#bookmarksBox.mobile .addForm, +#bookmarksBox.mobile .addForm *{ height:35px; padding:0; } -#sidebar #bookmarksBox .addForm a{ +#bookmarksBox.mobile .addForm a{ line-height:37px; } -#sidebar #bookmarksBox .addForm a{ +#bookmarksBox.mobile .addForm a{ width:25% !important; } -#sidebar #bookmarksBox .addForm input{ +#bookmarksBox.mobile .addForm input{ width:50% !important; text-indent:10px; } -#sidebar #bookmarksBox #bkmrk_portals .addForm input{ +#bookmarksBox.mobile #bkmrk_portals .addForm input{ width:75% !important; } -#sidebar #bookmarksBox #bookmarksTypeBar h5, -#sidebar #bookmarksBox .bookmarkList .addForm a{ +#bookmarksBox.mobile #bookmarksTypeBar h5, +#bookmarksBox.mobile .bookmarkList .addForm a{ box-shadow:-1px 0 0 #20a8b1 !important; } -#sidebar #bookmarksBox .bookmarkList li.bookmarkFolder ul{ +#bookmarksBox.mobile .bookmarkList li.bookmarkFolder ul{ display:none !important; min-height:37px !important; } @@ -500,26 +492,26 @@ padding:0 3px 1px 4px; background:#262c32; } -#sidebar #bookmarksBox .bookmarkList .bookmarkFolder .folderLabel .bookmarksAnchor span, -#sidebar #bookmarksBox .bookmarkList .bookmarkFolder .folderLabel > span, -#sidebar #bookmarksBox .bookmarkList .bookmarkFolder .folderLabel > span > span, -#sidebar #bookmarksBox .bookmarkList .triangle{ +#bookmarksBox.mobile .bookmarkList .bookmarkFolder .folderLabel .bookmarksAnchor span, +#bookmarksBox.mobile .bookmarkList .bookmarkFolder .folderLabel > span, +#bookmarksBox.mobile .bookmarkList .bookmarkFolder .folderLabel > span > span, +#bookmarksBox.mobile .bookmarkList .triangle{ width:0 !important; height:0 !important; } -#sidebar #bookmarksBox .bookmarkList .bookmarkFolder .folderLabel .bookmarksAnchor span{ +#bookmarksBox.mobile .bookmarkList .bookmarkFolder .folderLabel .bookmarksAnchor span{ float:left !important; border-width:5px 0 5px 7px !important; border-color:transparent transparent transparent white !important; margin:7px 3px 0 13px !important; } -#sidebar #bookmarksBox .bookmarkList .bookmarkFolder.open .folderLabel .bookmarksAnchor span{ +#bookmarksBox.mobile .bookmarkList .bookmarkFolder.open .folderLabel .bookmarksAnchor span{ margin:9px 1px 0 12px !important; border-width:7px 5px 0 5px !important; border-color:white transparent transparent transparent !important; } -#sidebar #bookmarksBox .bookmarkList .bookmarkFolder .folderLabel > span, -#sidebar #bookmarksBox .bookmarkList .bookmarkFolder .folderLabel > span > span{ +#bookmarksBox.mobile .bookmarkList .bookmarkFolder .folderLabel > span, +#bookmarksBox.mobile .bookmarkList .bookmarkFolder .folderLabel > span > span{ display:none !important; border-width:0 12px 10px 0 !important; border-color:transparent #20a8b1 transparent transparent !important; @@ -528,14 +520,14 @@ top:21px !important; left:-10px !important; } -#sidebar #bookmarksBox .bookmarkList .bookmarkFolder .folderLabel > span > span{ +#bookmarksBox.mobile .bookmarkList .bookmarkFolder .folderLabel > span > span{ top:18px !important; left:0 !important; border-width:0 10px 9px 0 !important; border-color:transparent #069 transparent transparent !important; } -#sidebar #bookmarksBox .bookmarkList .bookmarkFolder.open .folderLabel > span, -#sidebar #bookmarksBox .bookmarkList .bookmarkFolder.open .folderLabel > span > span{ +#bookmarksBox.mobile .bookmarkList .bookmarkFolder.open .folderLabel > span, +#bookmarksBox.mobile .bookmarkList .bookmarkFolder.open .folderLabel > span > span{ display:block !important; } /********************************************** @@ -605,4 +597,4 @@ width:96%; height:120px; resize:vertical; -} \ No newline at end of file +} diff --git a/plugins/broken/ap-list.user.js b/plugins/broken/ap-list.user.js index 4fc2bb23..87cc5b08 100644 --- a/plugins/broken/ap-list.user.js +++ b/plugins/broken/ap-list.user.js @@ -893,7 +893,7 @@ window.plugin.apList.setupPagination = function() { + '
' + '
' + '
' - + '
'// fix collapsion of parent caused by inner div's float:left + + '
'// fix collapsing of parent caused by inner div's float:left + '
'; $('#ap-list-pagination').html(content); } diff --git a/plugins/broken/draw-resonators.user.js b/plugins/broken/draw-resonators.user.js deleted file mode 100644 index 6e7ee025..00000000 --- a/plugins/broken/draw-resonators.user.js +++ /dev/null @@ -1,811 +0,0 @@ -// ==UserScript== -// @id iitc-plugin-draw-resonators@xelio -// @name IITC plugin: Draw resonators -// @category Layer -// @version 0.4.0.@@DATETIMEVERSION@@ -// @namespace https://github.com/jonatkins/ingress-intel-total-conversion -// @updateURL @@UPDATEURL@@ -// @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Draw resonators on map. With stylers to highlight resonators with specific criteria. -// @include https://www.ingress.com/intel* -// @include http://www.ingress.com/intel* -// @match https://www.ingress.com/intel* -// @match http://www.ingress.com/intel* -// @grant none -// ==/UserScript== - -@@PLUGINSTART@@ - -// PLUGIN START //////////////////////////////////////////////////////// - -// use own namespace for plugin -window.plugin.drawResonators = function() {}; - - -window.plugin.drawResonators.options; -window.plugin.drawResonators.render; - - - -//////// Render for handling render of resonators //////// - -// As long as 'window.Render.prototype.createPortalEntity' delete and recreate portal -// on any change of data, this resonator render should make resonator create and remove -// with portal correctly. -// -// Resonators will create when -// 1.Portal added to map -// 2.Zooming in to enable zoom level -// -// Resonators will remove when -// 1.Portal removed from map -// 2.Zooming out beyond enable zoom level - -window.plugin.drawResonators.Render = function(options) { - this.enableZoomLevel = options['enableZoomLevel']; - this.useStyler = ''; - - this.stylers = {}; - this.resonators = {}; - this.resonatorLayerGroup = new L.LayerGroup(); - this.addStyler(new window.plugin.drawResonators.Styler()); - this.beforeZoomLevel = map.getZoom(); - - this.portalAdded = this.portalAdded.bind(this); - this.createResonatorEntities = this.createResonatorEntities.bind(this); - this.deleteResonatorEntities = this.deleteResonatorEntities.bind(this); - this.handleResonatorEntitiesBeforeZoom = this.handleResonatorEntitiesBeforeZoom.bind(this); - this.handleResonatorEntitiesAfterZoom = this.handleResonatorEntitiesAfterZoom.bind(this); - this.handleEnableZoomLevelChange = this.handleEnableZoomLevelChange.bind(this); - this.portalSelectionChange = this.portalSelectionChange.bind(this); - this.changeStyler = this.changeStyler.bind(this); - this.getStylersList = this.getStylersList.bind(this); -}; - -window.plugin.drawResonators.Render.prototype.registerHook = function() { - window.addHook('portalAdded', this.portalAdded); - window.addHook('portalSelected', this.portalSelectionChange); - window.map.on('zoomstart', this.handleResonatorEntitiesBeforeZoom); - window.map.on('zoomend', this.handleResonatorEntitiesAfterZoom); -} - -window.plugin.drawResonators.Render.prototype.portalAdded = function(data) { - var marker = data.portal; - var render = this; - - marker.on('add', function() { - render.createResonatorEntities(this); // the 'this' in here is the portal. - }); - - marker.on('remove', function() { - render.deleteResonatorEntities(this.options.guid); // the 'this' in here is the portal. - }); -} - -window.plugin.drawResonators.Render.prototype.createResonatorEntities = function(portal) { - // No need to check for existing resonators, as old resonators should be removed with the portal marker. - - if(!this.isResonatorsShow()) return; - var portalDetails = portal.options.details; - var resonatorsWithConnector = new L.LayerGroup() - - var portalLatLng = [portalDetails.locationE6.latE6/1E6, portalDetails.locationE6.lngE6/1E6]; - var portalSelected = selectedPortal === portal.options.guid; - - for(var i in portalDetails.resonatorArray.resonators) { - resoData = portalDetails.resonatorArray.resonators[i]; - if(resoData === null) continue; - - var resoLatLng = this.getResonatorLatLng(resoData.distanceToPortal, resoData.slot, portalLatLng); - - var resoMarker = this.createResoMarker(resoData, resoLatLng, portalSelected); - var connMarker = this.createConnMarker(resoData, resoLatLng, portalLatLng, portalSelected); - - resonatorsWithConnector.addLayer(resoMarker); - resonatorsWithConnector.addLayer(connMarker); - } - - resonatorsWithConnector.options = { - details: portalDetails.resonatorArray.resonators, - guid: portal.options.guid - }; - - this.resonators[portal.options.guid] = resonatorsWithConnector; - this.resonatorLayerGroup.addLayer(resonatorsWithConnector); - - // bring portal in front of resonator connector - portal.bringToFront(); -} - -window.plugin.drawResonators.Render.prototype.createResoMarker = function(resoData, resoLatLng, portalSelected) { - var resoProperty = this.getStyler().getResonatorStyle(resoData, portalSelected); - resoProperty.type = 'resonator'; - resoProperty.details = resoData; - var reso = L.circleMarker(resoLatLng, resoProperty); - return reso; -} - -window.plugin.drawResonators.Render.prototype.createConnMarker = function(resoData, resoLatLng, portalLatLng, portalSelected) { - var connProperty = this.getStyler().getConnectorStyle(resoData, portalSelected); - connProperty.type = 'connector'; - connProperty.details = resoData; - var conn = L.polyline([portalLatLng, resoLatLng], connProperty); - return conn; -} - -window.plugin.drawResonators.Render.prototype.getResonatorLatLng = function(dist, slot, portalLatLng) { - // offset in meters - var dn = dist*SLOT_TO_LAT[slot]; - var de = dist*SLOT_TO_LNG[slot]; - - // Coordinate offset in radians - var dLat = dn/EARTH_RADIUS; - var dLon = de/(EARTH_RADIUS*Math.cos(Math.PI/180*portalLatLng[0])); - - // OffsetPosition, decimal degrees - var lat0 = portalLatLng[0] + dLat * 180/Math.PI; - var lon0 = portalLatLng[1] + dLon * 180/Math.PI; - - return [lat0, lon0]; -} - -window.plugin.drawResonators.Render.prototype.deleteResonatorEntities = function(portalGuid) { - if (!(portalGuid in this.resonators)) return; - - var r = this.resonators[portalGuid]; - this.resonatorLayerGroup.removeLayer(r); - delete this.resonators[portalGuid]; -} - -// Save zoom level before zoom, use to determine redraw of resonator -window.plugin.drawResonators.Render.prototype.handleResonatorEntitiesBeforeZoom = function() { - this.beforeZoomLevel = map.getZoom(); -} - -window.plugin.drawResonators.Render.prototype.handleResonatorEntitiesAfterZoom = function() { - if(!this.isResonatorsShow()) { - this.clearAllResonators(); - return; - } - - // Draw all resonators if they were not drawn - if(!this.isResonatorsShowBeforeZoom()) { - this.drawAllResonators(); - } -} - -window.plugin.drawResonators.Render.prototype.handleEnableZoomLevelChange = function(zoomLevel) { - this.enableZoomLevel = zoomLevel; - - if(!this.isResonatorsShow()) { - this.clearAllResonators(); - return; - } - - // Draw all resonators if they were not drawn - if(!Object.keys(this.resonators).length > 0) { - this.drawAllResonators(); - } -} - -window.plugin.drawResonators.Render.prototype.clearAllResonators = function() { - this.resonatorLayerGroup.clearLayers(); - this.resonators = {}; -} - -window.plugin.drawResonators.Render.prototype.drawAllResonators = function() { - var render = this; - - // loop through level of portals, only draw if the portal is shown on map - for (var guid in window.portals) { - var portal = window.portals[guid]; - // FIXME: need to find a proper way to check if a portal is added to the map without depending on leaflet internals - // (and without depending on portalsLayers either - that's IITC internal) - if (portal._map) { - render.createResonatorEntities(portal); - } - } -} - -window.plugin.drawResonators.Render.prototype.portalSelectionChange = function(data) { - this.toggleSelectedStyle(data.selectedPortalGuid); - this.toggleSelectedStyle(data.unselectedPortalGuid); -} - -window.plugin.drawResonators.Render.prototype.toggleSelectedStyle = function(portalGuid) { - if (!(portalGuid in this.resonators)) return; - - var render = this; - var portalSelected = selectedPortal === portalGuid; - var r = this.resonators[portalGuid]; - - r.eachLayer(function(entity) { - var style; - if(entity.options.type === 'resonator') { - style = render.getStyler().getResonatorStyle(entity.options.details, portalSelected); - } else { - style = render.getStyler().getConnectorStyle(entity.options.details, portalSelected); - } - - entity.setStyle(style); - }); -} - -window.plugin.drawResonators.Render.prototype.addStyler = function(styler) { - this.stylers[styler.name] = styler; -} - -window.plugin.drawResonators.Render.prototype.getStylersList = function() { - return Object.keys(this.stylers); -} - -window.plugin.drawResonators.Render.prototype.getStyler = function() { - var stylerName = this.useStyler in this.stylers ? this.useStyler : 'Default'; - return this.stylers[stylerName]; -} - -// Change if styler need change, and redraw all resonators using new styler -window.plugin.drawResonators.Render.prototype.changeStyler = function(name) { - if (name === this.useStyler) return; - for(stylerName in this.stylers) { - if(stylerName === name) { - if(this.stylers[this.useStyler]) this.stylers[this.useStyler].onDisableFunc(); - this.useStyler = stylerName; - this.stylers[this.useStyler].onEnableFunc(); - this.clearAllResonators(); - this.drawAllResonators(); - return; - } - } -} - -window.plugin.drawResonators.Render.prototype.refreshStyler = function() { - this.clearAllResonators(); - this.drawAllResonators(); -} - -window.plugin.drawResonators.Render.prototype.isResonatorsShow = function() { - return map.getZoom() >= this.enableZoomLevel; -} - -window.plugin.drawResonators.Render.prototype.isResonatorsShowBeforeZoom = function() { - return this.beforeZoomLevel >= this.enableZoomLevel; -} - - - -//////// Styler for getting resonator and connector style //////// - - - -window.plugin.drawResonators.Styler = function(options) { - options = options || {}; - this.name = options['name'] || 'Default'; - this.otherOptions = options['otherOptions']; - this.getResonatorStyle = options['resonatorStyleFunc'] || this.defaultResonatorStyle; - this.getConnectorStyle = options['connectorStyleFunc'] || this.defaultConnectorStyle; - this.onEnableFunc = options['onEnableFunc'] || function() {}; - this.onDisableFunc = options['onDisableFunc'] || function() {}; -} - -window.plugin.drawResonators.Styler.prototype.DEFAULT_OPTIONS_RESONATOR_SELECTED = { - color: '#fff', - weight: 1.1, - radius: 4, - opacity: 1, - clickable: false}; - -window.plugin.drawResonators.Styler.prototype.DEFAULT_OPTIONS_RESONATOR_NON_SELECTED = { - color: '#aaa', - weight: 1, - radius: 3, - opacity: 1, - clickable: false}; - -window.plugin.drawResonators.Styler.prototype.DEFAULT_OPTIONS_RESONATOR_LINE_SELECTED = { - opacity: 0.7, - weight: 3, - color: '#FFA000', - dashArray: '0,10' + (new Array(25).join(',8,4')), - fill: false, - clickable: false}; - -window.plugin.drawResonators.Styler.prototype.DEFAULT_OPTIONS_RESONATOR_LINE_NON_SELECTED = { - opacity: 0.25, - weight: 2, - color: '#FFA000', - dashArray: '0,10' + (new Array(25).join(',8,4')), - fill: false, - clickable: false}; - -window.plugin.drawResonators.Styler.prototype.defaultResonatorStyle = function(resoDetail, selected) { - var resoSharedStyle = selected - ? this.DEFAULT_OPTIONS_RESONATOR_SELECTED - : this.DEFAULT_OPTIONS_RESONATOR_NON_SELECTED; - - var resoStyle = $.extend({ - fillColor: COLORS_LVL[resoDetail.level], - fillOpacity: resoDetail.energyTotal/RESO_NRG[resoDetail.level], - }, resoSharedStyle); - - return resoStyle; -} - -window.plugin.drawResonators.Styler.prototype.defaultConnectorStyle = function(resoDetail, selected) { - var connStyle = selected - ? this.DEFAULT_OPTIONS_RESONATOR_LINE_SELECTED - : this.DEFAULT_OPTIONS_RESONATOR_LINE_NON_SELECTED; - - return connStyle; -} - - - -//////// Options for storing and loading options //////// - - - -window.plugin.drawResonators.Options = function() { - this._options = {}; - this._callbacks = {}; -} - -window.plugin.drawResonators.Options.prototype.addCallback = function(name, callback) { - if (!this._callbacks[name]) { - this._callbacks[name] = []; - } - this._callbacks[name].push(callback); -} - -window.plugin.drawResonators.Options.prototype.newOption = function(name, defaultValue) { - this._options[name] = this.loadLocal(this.getStorageKey(name), defaultValue) -} - -window.plugin.drawResonators.Options.prototype.getOption = function(name) { - return this._options[name]; -} - -window.plugin.drawResonators.Options.prototype.removeOption = function(name) { - delete this._options[name]; - delete this._callbacks[name]; -} - -window.plugin.drawResonators.Options.prototype.changeOption = function(name, value) { - if(!(name in this._options)) return false; - if(value === this._options[name]) return false; - - this._options[name] = value; - this.storeLocal(this.getStorageKey(name), this._options[name]); - - if (this._callbacks[name] !== null) { - for(var i in this._callbacks[name]) { - this._callbacks[name][i](value); - } - } -} - -window.plugin.drawResonators.Options.prototype.getStorageKey = function(name) { - return 'plugin-drawResonators-option-' + name; -} - -window.plugin.drawResonators.Options.prototype.loadLocal = function(key, defaultValue) { - var objectJSON = localStorage[key]; - if(objectJSON) { - return JSON.parse(objectJSON); - } else { - return defaultValue; - } -} - -window.plugin.drawResonators.Options.prototype.storeLocal = function(key, value) { - if(typeof(value) !== 'undefined' && value !== null) { - localStorage[key] = JSON.stringify(value); - } else { - localStorage.removeItem(key); - } -} - - - -//////// Dialog - -window.plugin.drawResonators.Dialog = function() { - this._dialogEntries = {}; -} - -window.plugin.drawResonators.Dialog.prototype.addLink = function() { - $('#toolbox').append('
Resonators '); -} - -window.plugin.drawResonators.Dialog.prototype.addEntry = function(name, dialogEntry) { - this._dialogEntries[name] = dialogEntry; - this.change(); -} - -window.plugin.drawResonators.Dialog.prototype.removeEntry = function(name) { - delete this._dialogEntries[name]; - this.change(); -} - -window.plugin.drawResonators.Dialog.prototype.show = function() { - window.dialog({html: this.getDialogHTML(), title: 'Resonators', modal: true, id: 'draw-reso-setting'}); - - // Attach entries event - for(var name in this._dialogEntries) { - var events = this._dialogEntries[name].getOnEvents(); - for(var i in events) { - var event = events[i]; - $('#draw-reso-dialog').on(event.event, '#' + event.id, event.callback); - } - } -} - -window.plugin.drawResonators.Dialog.prototype.change = function() { - if($('#draw-reso-dialog').length > 0) this.show(); -} - -window.plugin.drawResonators.Dialog.prototype.getDialogHTML = function() { - var html = '
' - for(var name in this._dialogEntries) { - html += '
' - + this._dialogEntries[name].getHTML() - + '
'; - } - html += '
'; - return html; -} - - - -//////// ListDialogEntry - - - -window.plugin.drawResonators.ListDialogEntry = function(options) { - this._name = options['name']; - this._label = options['label']; - this._valueFunc = options['valueFunc']; - this._valuesList = options['valuesList']; - this._valuesListFunc = options['valuesListFunc']; - this._onChangeCallback = options['onChangeCallback']; -} - -window.plugin.drawResonators.ListDialogEntry.prototype.getHTML = function() { - var curValue = this._valueFunc(); - var valuesList = this._valuesList ? this._valuesList : this._valuesListFunc(); - var html = '' - + ''; - return html; -} - -window.plugin.drawResonators.ListDialogEntry.prototype.getOnEvents = function() { - return [{'event': 'change', - 'id': this.getSelectId(), - 'callback': this._onChangeCallback - }]; -} - -window.plugin.drawResonators.ListDialogEntry.prototype.getSelectId = function() { - return 'draw-reso-option-' + this._name; -} - - - -//////// TextboxDialogEntry - - -window.plugin.drawResonators.TextboxDialogEntry = function(options) { - this._name = options['name']; - this._label = options['label']; - this._valueFunc = options['valueFunc']; - this._onChangeCallback = options['onChangeCallback']; -} - -window.plugin.drawResonators.TextboxDialogEntry.prototype.getHTML = function() { - var curValue = this._valueFunc(); - var html = '' - + ''; - return html; -} - - -window.plugin.drawResonators.TextboxDialogEntry.prototype.getOnEvents = function() { - return [{'event': 'change', - 'id': this.getInputId(), - 'callback': this._onChangeCallback - }]; -} - -window.plugin.drawResonators.TextboxDialogEntry.prototype.getInputId = function() { - return 'draw-reso-option-' + this._name; -} - - - -window.plugin.drawResonators.setupStyler = function() { - var thisPlugin = window.plugin.drawResonators; - - var highlightedReso = {color: '#fff', weight: 2, radius: 4, opacity: 1, clickable: false}; - var normalReso = {color: '#aaa', weight: 1, radius: 3, opacity: 1, clickable: false}; - var selectedReso = {color: '#eee', weight: 1.1, radius: 4, opacity: 1, clickable: false}; - var highlightedConn = {opacity: 0.7, weight: 3, color: '#FFA000', dashArray: '0,10,999', color: '#FFA000', fill: false, clickable: false}; - var normalConn = {opacity: 0.25, weight: 2, color: '#FFA000', dashArray: '0,10' + (new Array(25).join(',8,4')), fill: false, clickable: false}; - var selectedConn = {opacity: 0.7, weight: 3, color: '#FFA000', dashArray: '0,10' + (new Array(25).join(',8,4')), fill: false, clickable: false}; - - // Styler for highlighting resonators deployed by me - var myReso = { - name: 'Highlight my resonators', - otherOptions: { - 'highlightedReso' : highlightedReso, - 'normalReso' : normalReso, - 'selectedReso' : selectedReso, - 'highlightedConn' : highlightedConn, - 'normalConn' : normalConn, - 'selectedConn' : selectedConn - }, - resonatorStyleFunc: function(resoDetail, selected) { - var mine = resoDetail.ownerGuid === PLAYER.guid; - var resoSharedStyle = mine - ? this.otherOptions.highlightedReso - : (selected ? this.otherOptions.selectedReso : this.otherOptions.normalReso); - - var resoStyle = $.extend({ - fillColor: COLORS_LVL[resoDetail.level], - fillOpacity: resoDetail.energyTotal/RESO_NRG[resoDetail.level] * (mine ? 1 : 0.75) - }, resoSharedStyle); - return resoStyle; - }, - connectorStyleFunc: function(resoDetail, selected) { - var mine = resoDetail.ownerGuid === PLAYER.guid; - var connStyle = mine - ? this.otherOptions.highlightedConn - : (selected ? this.otherOptions.selectedConn : this.otherOptions.normalConn); - return connStyle; - } - }; - - thisPlugin.render.addStyler(new thisPlugin.Styler(myReso)); - - // Styler for highlighting L8 resonators - var l8Reso = { - name: 'Highlight L8 resonators', - otherOptions: { - 'highlightedReso' : highlightedReso, - 'normalReso' : normalReso, - 'selectedReso' : selectedReso, - 'highlightedConn' : highlightedConn, - 'normalConn' : normalConn, - 'selectedConn' : selectedConn - }, - resonatorStyleFunc: function(resoDetail, selected) { - var l8 = resoDetail.level === 8; - var resoSharedStyle = l8 - ? this.otherOptions.highlightedReso - : (selected ? this.otherOptions.selectedReso : this.otherOptions.normalReso); - - var resoStyle = $.extend({ - fillColor: COLORS_LVL[resoDetail.level], - fillOpacity: resoDetail.energyTotal/RESO_NRG[resoDetail.level] * (l8 ? 1 : 0.75) - }, resoSharedStyle); - return resoStyle; - }, - connectorStyleFunc: function(resoDetail, selected) { - var l8 = resoDetail.level === 8; - var connStyle = l8 - ? this.otherOptions.highlightedConn - : (selected ? this.otherOptions.selectedConn : this.otherOptions.normalConn); - return connStyle; - } - }; - - thisPlugin.render.addStyler(new thisPlugin.Styler(l8Reso)); - - // Styler for highlighting resonators with less than X% energy - var lessThanXPctReso = { - name: 'Highlight < X% resonators', - otherOptions: { - 'highlightedReso': highlightedReso, - 'normalReso': normalReso, - 'selectedReso': selectedReso, - 'highlightedConn': highlightedConn, - 'normalConn': normalConn, - 'selectedConn': selectedConn, - 'pct': 15, - 'dialogEntry': new thisPlugin.TextboxDialogEntry({ - name: 'resoLessThanPct-pct', - label: 'Percentage', - valueFunc: function() {return thisPlugin.options.getOption('styler-resoLessThanPct-pct')}, - onChangeCallback: function(event) {thisPlugin.options.changeOption('styler-resoLessThanPct-pct', parseInt(event.target.value));} - }) - }, - resonatorStyleFunc: function(resoDetail, selected) { - var highlight = (resoDetail.energyTotal * 100) < (RESO_NRG[resoDetail.level] * this.otherOptions.pct); - var resoSharedStyle = highlight - ? this.otherOptions.highlightedReso - : (selected ? this.otherOptions.selectedReso : this.otherOptions.normalReso); - - var resoStyle = $.extend({ - fillColor: COLORS_LVL[resoDetail.level], - fillOpacity: resoDetail.energyTotal/RESO_NRG[resoDetail.level] - }, resoSharedStyle); - return resoStyle; - }, - connectorStyleFunc: function(resoDetail, selected) { - var highlight = (resoDetail.energyTotal * 100) < (RESO_NRG[resoDetail.level] * this.otherOptions.pct); - var connStyle = highlight - ? this.otherOptions.highlightedConn - : (selected ? this.otherOptions.selectedConn : this.otherOptions.normalConn); - return connStyle; - }, - onEnableFunc: function() { - var thisPlugin = window.plugin.drawResonators; - var thisStyler = this; - // Add option - thisPlugin.options.newOption('styler-resoLessThanPct-pct', 15); - thisPlugin.options.addCallback('styler-resoLessThanPct-pct', function(value) { - thisStyler.otherOptions.pct = value; - thisPlugin.render.refreshStyler(); - }); - thisStyler.otherOptions.pct = thisPlugin.options.getOption('styler-resoLessThanPct-pct'); - // Add dialog entry - thisPlugin.dialog.addEntry('resoLessThanPct-pct', this.otherOptions.dialogEntry); - }, - onDisableFunc: function() { - var thisPlugin = window.plugin.drawResonators; - // Remove option - thisPlugin.options.removeOption('styler-resoLessThanPct-pct'); - // Remove dialog entry - thisPlugin.dialog.removeEntry('resoLessThanPct-pct'); - } - }; - - thisPlugin.render.addStyler(new thisPlugin.Styler(lessThanXPctReso)); - - // Styler for highlighting resonators deployed by specific player - var resoOfSpecificPlayer = { - name: 'Highlight resonators by player', - otherOptions: { - 'highlightedReso': highlightedReso, - 'normalReso': normalReso, - 'selectedReso': selectedReso, - 'highlightedConn': highlightedConn, - 'normalConn': normalConn, - 'selectedConn': selectedConn, - 'player': '', - 'playerGuid': '', - 'dialogEntry': new thisPlugin.TextboxDialogEntry({ - name: 'resoOfSpecificPlayer-player', - label: 'Player name', - valueFunc: function() {return thisPlugin.options.getOption('styler-resoOfSpecificPlayer-player')}, - onChangeCallback: function(event) {thisPlugin.options.changeOption('styler-resoOfSpecificPlayer-player', event.target.value);} - }) - }, - resonatorStyleFunc: function(resoDetail, selected) { - var highlight = resoDetail.ownerGuid === this.otherOptions.playerGuid; - var resoSharedStyle = highlight - ? this.otherOptions.highlightedReso - : (selected ? this.otherOptions.selectedReso : this.otherOptions.normalReso); - - var resoStyle = $.extend({ - fillColor: COLORS_LVL[resoDetail.level], - fillOpacity: resoDetail.energyTotal/RESO_NRG[resoDetail.level] * (highlight ? 1 : 0.75) - }, resoSharedStyle); - return resoStyle; - }, - connectorStyleFunc: function(resoDetail, selected) { - var highlight = resoDetail.ownerGuid === this.otherOptions.playerGuid; - var connStyle = highlight - ? this.otherOptions.highlightedConn - : (selected ? this.otherOptions.selectedConn : this.otherOptions.normalConn); - return connStyle; - }, - onEnableFunc: function() { - var thisPlugin = window.plugin.drawResonators; - var thisStyler = this; - // Add option - thisPlugin.options.newOption('styler-resoOfSpecificPlayer-player', ''); - thisPlugin.options.addCallback('styler-resoOfSpecificPlayer-player', function(value) { - thisStyler.otherOptions.player = value; - thisStyler.otherOptions.playerGuid = window.playerNameToGuid(value); - thisPlugin.render.refreshStyler(); - }); - thisStyler.otherOptions.player = thisPlugin.options.getOption('styler-resoOfSpecificPlayer-player'); - thisStyler.otherOptions.playerGuid = window.playerNameToGuid(thisStyler.otherOptions.player); - // Add dialog entry - thisPlugin.dialog.addEntry('resoOfSpecificPlayer-player', this.otherOptions.dialogEntry); - }, - onDisableFunc: function() { - var thisPlugin = window.plugin.drawResonators; - // Remove option - thisPlugin.options.removeOption('styler-resoOfSpecificPlayer-player'); - // Remove dialog entry - thisPlugin.dialog.removeEntry('resoOfSpecificPlayer-player'); - } - }; - - thisPlugin.render.addStyler(new thisPlugin.Styler(resoOfSpecificPlayer)); - - thisPlugin.render.changeStyler(thisPlugin.options.getOption('useStyler')); -} - - -window.plugin.drawResonators.setupOptions = function() { - var thisPlugin = window.plugin.drawResonators; - // Initialize options - thisPlugin.options = new thisPlugin.Options(); - thisPlugin.options.newOption('enableZoomLevel', 17); - thisPlugin.options.newOption('useStyler', 'Default'); -} - -window.plugin.drawResonators.setupDialog = function() { - var thisPlugin = window.plugin.drawResonators; - // Initialize dialog - thisPlugin.dialog = new thisPlugin.Dialog(); - - var enableZoomLevelDialogEntryOptions = { - name: 'enable-zoom-level', - label: 'Enable zoom level', - valueFunc: function() {return thisPlugin.options.getOption('enableZoomLevel')}, - valuesList: {'15':15, '16':16, '17':17, '18':18, '19':19, '20':20, 'None':99}, - onChangeCallback: function(event) {thisPlugin.options.changeOption('enableZoomLevel', parseInt(event.target.value));} - }; - var enableZoomLevelDialogEntry = new thisPlugin.ListDialogEntry(enableZoomLevelDialogEntryOptions); - thisPlugin.dialog.addEntry('enable-zoom-level', enableZoomLevelDialogEntry); - - var stylerDialogEntryOptions = { - name: 'use-styler', - label: 'Styler', - valueFunc: function() {return thisPlugin.options.getOption('useStyler')}, - valuesListFunc: thisPlugin.render.getStylersList, - onChangeCallback: function(event) {thisPlugin.options.changeOption('useStyler', event.target.value);} - }; - var stylerDialogEntry = new thisPlugin.ListDialogEntry(stylerDialogEntryOptions); - thisPlugin.dialog.addEntry('use-styler', stylerDialogEntry); - - thisPlugin.dialog.addLink(); -} - -var setup = function() { - var thisPlugin = window.plugin.drawResonators; - - // Initialize options - thisPlugin.setupOptions(); - - // Initialize render - var renderOptions = {'enableZoomLevel': thisPlugin.options.getOption('enableZoomLevel')}; - - thisPlugin.render = new thisPlugin.Render(renderOptions); - - // callback run at option change - thisPlugin.options.addCallback('enableZoomLevel', thisPlugin.render.handleEnableZoomLevelChange); - thisPlugin.options.addCallback('useStyler', thisPlugin.render.changeStyler); - - // Initialize Dialog - thisPlugin.setupDialog(); - // Initialize styler - thisPlugin.setupStyler(); - - thisPlugin.render.registerHook(); - window.addLayerGroup('Resonators', thisPlugin.render.resonatorLayerGroup, true); -} - -// PLUGIN END ////////////////////////////////////////////////////////// - -@@PLUGINEND@@ diff --git a/plugins/broken/ipas-link.user.js b/plugins/broken/ipas-link.user.js deleted file mode 100644 index 02db5180..00000000 --- a/plugins/broken/ipas-link.user.js +++ /dev/null @@ -1,111 +0,0 @@ -// ==UserScript== -// @id iitc-plugin-ipas-link@graphracer -// @name IITC Plugin: simulate an attack on portal -// @category Portal Info -// @version 0.2.0.@@DATETIMEVERSION@@ -// @namespace https://github.com/xosofox/IPAS -// @updateURL @@UPDATEURL@@ -// @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Adds a link to the portal details to open the portal in IPAS - Ingress Portal Attack Simulator on http://ipas.graphracer.com -// @include https://www.ingress.com/intel* -// @include http://www.ingress.com/intel* -// @match https://www.ingress.com/intel* -// @match http://www.ingress.com/intel* -// @grant none -// ==/UserScript== - -@@PLUGINSTART@@ - -// PLUGIN START //////////////////////////////////////////////////////// - -// use own namespace for plugin -window.plugin.ipasLink = function() {}; - -window.plugin.ipasLink.setupCallback = function() { - addHook('portalDetailsUpdated', window.plugin.ipasLink.addLink); -} - -window.plugin.ipasLink.addLink = function(d) { - $('.linkdetails').append(''); -} - -window.plugin.ipasLink.getHash = function (d) { - var hashParts = []; - $.each(d.resonatorArray.resonators, function (ind, reso) { - if (reso) { - hashParts.push(reso.level + "," + reso.distanceToPortal + "," + reso.energyTotal); - } else { - hashParts.push("1,20,0"); - } - }); - var resos = hashParts.join(";"); - - hashParts = []; - $.each(d.portalV2.linkedModArray, function (ind, mod) { - // s - shields - // h - heat sink - // i - intentionally left in - // t - turret - // - // f - force amp - // m - multi-hack - // l - link-amp - // - var modCodes = { - "RES_SHIELD": "s", - "HEATSINK": "h", - "TURRET": "t", - "FORCE_AMP": "f", - "MULTIHACK": "m", - "LINK_AMPLIFIER": "l" - } - - var mc = "0"; - if (mod) { - if (mod.type in modCodes) { - mc = modCodes[mod.type] + mod.rarity.charAt(0).toLowerCase(); - - //special for shields to distinguish old/new mitigation - if (mod.type == "RES_SHIELD") { - mc += mod.stats.MITIGATION; - } - } - } - hashParts.push(mc); - }); - var shields = hashParts.join(","); - - var linkParts = []; - var edges = d.portalV2.linkedEdges; - - var portalL = new L.LatLng(d.locationE6.latE6 / 1E6, d.locationE6.lngE6 / 1E6) - $.each(edges, function (ind, edge) { - //calc distance in m here - var distance = 1; //default to 1m, so a low level portal would support it - - //Try to find other portals details - var guid = edge.otherPortalGuid - if (window.portals[guid] !== undefined) { - //get other portals details as o - var o = window.portals[guid].options.details; - var otherPortalL = new L.LatLng(o.locationE6.latE6 / 1E6, o.locationE6.lngE6 / 1E6); - var distance = Math.round(portalL.distanceTo(otherPortalL)); - } - - if (!(edge.isOrigin)) { - distance = distance * -1; - } - linkParts.push(distance); - }); - var links = linkParts.join(","); - - return resos + "/" + shields + "/" + links; //changed with IPAS 1.1 to / instead of | - } - -var setup = function () { - window.plugin.ipasLink.setupCallback(); -} - -// PLUGIN END ////////////////////////////////////////////////////////// - -@@PLUGINEND@@ diff --git a/plugins/broken/portal-defense.user.js b/plugins/broken/portal-defense.user.js index 9f95ce4d..e4a430dc 100644 --- a/plugins/broken/portal-defense.user.js +++ b/plugins/broken/portal-defense.user.js @@ -6,7 +6,7 @@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Shows the defense values of every portal (see also "hightlight portals total mitigation" highlighter) +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Shows the defense values of every portal (see also "highlight portals total mitigation" highlighter) // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* @@ -68,7 +68,7 @@ window.plugin.portalDefense.renderAttackRegion = function(portal) { } var region = L.marker(portal.getLatLng(), { icon: L.divIcon({ - className: 'plugin-iic-defense', + className: 'plugin-iitc-defense', clickable: false, iconAnchor: [-10,10], html: "
"+display+"
" @@ -127,7 +127,7 @@ var setup = function() { $('#toolbox').append(' Reload Defense'); $("'); - // Setup sorting - $(document).on('click.portalslist', '#portalslist table th', function() { - $('#portalslist').html(window.plugin.portalslist.portalTable($(this).data('sort'),window.plugin.portalslist.sortOrder,window.plugin.portalslist.filter)); - }); - $(document).on('click.portalslist', '#portalslist .filterAll', function() { - $('#portalslist').html(window.plugin.portalslist.portalTable($(this).data('sort'),window.plugin.portalslist.sortOrder,0)); - }); - $(document).on('click.portalslist', '#portalslist .filterRes', function() { - $('#portalslist').html(window.plugin.portalslist.portalTable($(this).data('sort'),window.plugin.portalslist.sortOrder,1)); - }); - $(document).on('click.portalslist', '#portalslist .filterEnl', function() { - $('#portalslist').html(window.plugin.portalslist.portalTable($(this).data('sort'),window.plugin.portalslist.sortOrder,2)); - }); -} - -// PLUGIN END ////////////////////////////////////////////////////////// - -@@PLUGINEND@@ diff --git a/plugins/debug-raw-portal-data.user.js b/plugins/debug-raw-portal-data.user.js index db87f1c4..5df1faf8 100644 --- a/plugins/debug-raw-portal-data.user.js +++ b/plugins/debug-raw-portal-data.user.js @@ -6,7 +6,7 @@ // @namespace rawdata // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Developer debugging aid: Adds a link to the portal details to show the raw data of a portal +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Developer debugging aid: Add a link to the portal details to show the raw data of a portal. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* diff --git a/plugins/draw-resonators.user.js b/plugins/draw-resonators.user.js index f85d3b2f..9111ede7 100644 --- a/plugins/draw-resonators.user.js +++ b/plugins/draw-resonators.user.js @@ -1,15 +1,146 @@ // ==UserScript== // @id iitc-plugin-draw-resonators@xelio // @name IITC plugin: Draw resonators -// @category Deleted -// @version 0.4.0.@@DATETIMEVERSION@@ +// @category Layer +// @version 0.5.0.@@DATETIMEVERSION@@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description PLUGIN CURRENTLY UNAVAILABLE +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Draw resonators on map for currently selected portal. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* // @match http://www.ingress.com/intel* // @grant none // ==/UserScript== + +@@PLUGINSTART@@ + +// PLUGIN START //////////////////////////////////////////////////////// +window.RESONATOR_MIN_ZOOM = 16; + +// use own namespace for plugin +window.plugin.drawResonators = function() {}; + +window.plugin.drawResonators.levelLayerGroup = null; + +window.plugin.drawResonators.portalSelected = function(data) { + // new portal selected - clear any existing resonators.. + window.plugin.drawResonators.levelLayerGroup.clearLayers(); + + // then, if a portal is selected... + if (data.selectedPortalGuid) { + // draw it's resonators if we have it's details + var details = portalDetail.get(data.selectedPortalGuid); + if (details) { + window.plugin.drawResonators.drawData(details); + } + } +} + +window.plugin.drawResonators.portalDetailLoaded = function(data) { + // the detailed data for a portal was just loaded - if this is the selected portal, draw them + + if (data.guid == window.selectedPortal) { + window.plugin.drawResonators.levelLayerGroup.clearLayers(); + window.plugin.drawResonators.drawData(data.details); + } +} + +window.plugin.drawResonators.drawData = function(portalDetails) { + if(window.map.getZoom() < window.RESONATOR_MIN_ZOOM) return; + + var portalLatLng = [portalDetails.locationE6.latE6/1E6, portalDetails.locationE6.lngE6/1E6]; + for(var i in portalDetails.resonatorArray.resonators) { + resoData = portalDetails.resonatorArray.resonators[i]; + if(resoData === null) continue; + + var resoLatLng = window.plugin.drawResonators.getResonatorLatLng(resoData.distanceToPortal, resoData.slot, portalLatLng); + + var resoMarker = window.plugin.drawResonators.createResoMarker(resoData, resoLatLng); + var connMarker = window.plugin.drawResonators.createConnMarker(resoData, resoLatLng, portalLatLng); + + window.plugin.drawResonators.levelLayerGroup.addLayer(resoMarker); + window.plugin.drawResonators.levelLayerGroup.addLayer(connMarker); + } +} + +window.plugin.drawResonators.getResonatorLatLng = function(dist, slot, portalLatLng) { + // offset in meters + var dn = dist*SLOT_TO_LAT[slot]; + var de = dist*SLOT_TO_LNG[slot]; + + // Coordinate offset in radians + var dLat = dn/EARTH_RADIUS; + var dLon = de/(EARTH_RADIUS*Math.cos(Math.PI/180*portalLatLng[0])); + + // OffsetPosition, decimal degrees + var lat0 = portalLatLng[0] + dLat * 180/Math.PI; + var lon0 = portalLatLng[1] + dLon * 180/Math.PI; + + return [lat0, lon0]; +} + +window.plugin.drawResonators.createResoMarker = function(resoData, resoLatLng) { + var resoProperty = { + fillColor: COLORS_LVL[resoData.level], + fillOpacity: resoData.energyTotal/RESO_NRG[resoData.level], + color: '#aaa', + weight: 1, + radius: 3, + opacity: 1, + clickable: false}; + resoProperty.type = 'resonator'; + resoProperty.details = resoData; + var reso = L.circleMarker(resoLatLng, resoProperty); + return reso; +} + +window.plugin.drawResonators.createConnMarker = function(resoData, resoLatLng, portalLatLng) { + var connProperty = { + opacity: 0.25, + weight: 2, + color: '#FFA000', + dashArray: '0,10' + (new Array(25).join(',8,4')), + fill: false, + clickable: false}; + connProperty.type = 'connector'; + connProperty.details = resoData; + var conn = L.polyline([portalLatLng, resoLatLng], connProperty); + return conn; +} + +window.plugin.drawResonators.zoomListener = function() { + var ctrl = $('.leaflet-control-layers-selector + span:contains("Resonators")').parent(); + if(window.map.getZoom() < window.RESONATOR_MIN_ZOOM) { + window.plugin.drawResonators.levelLayerGroup.clearLayers(); + ctrl.addClass('disabled').attr('title', 'Zoom in to show those.'); + } else { + ctrl.removeClass('disabled').attr('title', 'Select a portal to draw resos'); + window.plugin.drawResonators.levelLayerGroup.clearLayers(); + if (window.selectedPortal) { + var details = portalDetail.get(window.selectedPortal); + if (details) { + window.plugin.drawResonators.drawData(details); + } + } + }; +} + +var setup = function() { + + window.plugin.drawResonators.levelLayerGroup = new L.LayerGroup(); + + window.addLayerGroup('Resonators', window.plugin.drawResonators.levelLayerGroup, true); + + window.addHook('portalSelected', window.plugin.drawResonators.portalSelected); + window.addHook('portalDetailLoaded', window.plugin.drawResonators.portalDetailLoaded); + + window.map.on('zoomend', function() { + window.plugin.drawResonators.zoomListener(); + }); + +} +// PLUGIN END ////////////////////////////////////////////////////////// + +@@PLUGINEND@@ diff --git a/plugins/draw-tools.user.js b/plugins/draw-tools.user.js index ef28b8f8..c254acc1 100644 --- a/plugins/draw-tools.user.js +++ b/plugins/draw-tools.user.js @@ -6,7 +6,7 @@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Allows you to draw things into the current map so you may plan your next move +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Allow drawing things onto the current map so you may plan your next move. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* diff --git a/plugins/force-https.user.js b/plugins/force-https.user.js index 18516582..c29ae7cd 100644 --- a/plugins/force-https.user.js +++ b/plugins/force-https.user.js @@ -6,7 +6,7 @@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Force https access for ingress.com/intel. If the intel site is accessed via http, it redirects to the https version +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Force https access for ingress.com/intel. If the intel site is accessed via http, it redirects to the https version. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* diff --git a/plugins/guess-player-levels.user.js b/plugins/guess-player-levels.user.js index b51de2cd..364caa16 100644 --- a/plugins/guess-player-levels.user.js +++ b/plugins/guess-player-levels.user.js @@ -2,11 +2,11 @@ // @id iitc-plugin-guess-player-levels@breunigs // @name IITC plugin: guess player level // @category Info -// @version 0.5.0.@@DATETIMEVERSION@@ +// @version 0.5.1.@@DATETIMEVERSION@@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Tries to determine player levels from the data available in the current view +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Try to determine player levels from the data available in the current view. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* @@ -86,13 +86,17 @@ window.plugin.guessPlayerLevels.setLevelTitle = function(dom) { var details = window.plugin.guessPlayerLevels.fetchLevelDetailsByPlayer(nick); - var text; + function getLevel(lvl) { + return ''+lvl+''; + } + + var text = '' + nick + '\n'; if(details.min == 8) - text = 'Player level: 8'; + text += 'Player level: ' + getLevel(8); else { - text = 'Min player level: ' + details.min; + text += 'Min player level: ' + getLevel(details.min); if(details.min != details.guessed) - text += '\nGuessed player level: ' + details.guessed; + text += '\nGuessed player level: ' + getLevel(details.guessed); } window.setupTooltips(el); @@ -119,56 +123,80 @@ window.plugin.guessPlayerLevels.extractPortalData = function(data) { var r = data.details.resonatorArray.resonators; - //due to the Jarvis Virus/ADA Refactor it's possible for a player to own resonators on a portal - //at a higher level than the player themselves. It is not possible to detect for sure when this - //has happened, but in many cases it will result in an impossible deployment arrangement - //(over 1 L8/7 res, over 2 L6/5 res, etc). if we detect this case, ignore all resonators owned - //by that player on the portal + /* Due to the Jarvis Virus/ADA Refactor it's possible for a player to own resonators on a portal at a higher level + than the player themselves. It is not possible to detect for sure when this has happened, but in many cases it will + result in an impossible deployment arrangement (more than 1 L8/7 res, more than 2 L6/5 res, etc). If we detect this + case, we ignore all resonators owned by that player on the portal + Hint: This can only happen to the owner of the portal, so resonators by other players can be used to determine + their minimal level */ -// TODO? go further, and just ignore all resonators owned by the portal owner? -// or; have a 'guessed' level and a 'certain' level. 'certain' comes from res from non-owner, and COMM deploy -// while 'guessed' comes from resonators of the portal owner + var owner = data.details.captured && data.details.captured.capturingPlayerId || ""; + var ownerModCount = 0; + data.details.portalV2.linkedModArray.forEach(function(mod) { + if(mod && mod.installingUser == owner) + ownerModCount++; + }); - var perPlayerResMaxLevel = {}; - var perPlayerResMaxLevelCount = {}; + var players = {}; $.each(r, function(ind, reso) { if(!reso) return true; - if(!perPlayerResMaxLevel[reso.ownerGuid] || reso.level > perPlayerResMaxLevel[reso.ownerGuid]) { - perPlayerResMaxLevel[reso.ownerGuid] = reso.level; - perPlayerResMaxLevelCount[reso.ownerGuid] = 0; - } - if (reso.level == perPlayerResMaxLevel[reso.ownerGuid]) perPlayerResMaxLevelCount[reso.ownerGuid]++; + if(!players[reso.ownerGuid]) players[reso.ownerGuid] = []; + + if(players[reso.ownerGuid][reso.level] === undefined) + players[reso.ownerGuid][reso.level] = 1 + else + players[reso.ownerGuid][reso.level]++; }); - $.each(perPlayerResMaxLevel, function(guid, level) { - if (perPlayerResMaxLevelCount[guid] <= window.MAX_RESO_PER_PLAYER[level]) { - window.plugin.guessPlayerLevels.savePlayerLevel(guid, level); + for(nickname in players) { + var ignore = false; + var minLevel = 0; + + if(nickname == owner) { + if(ownerModCount > 2) // more than 2 mods by capturing player --> portal was flipped, ignore their resonators + continue; + var certain = false; + } else { // not deployed by owner - player must be at least that level + var certain = true; } - }); + + players[nickname].forEach(function(count, level) { + if(MAX_RESO_PER_PLAYER[level] < count) + ignore = true; + + if(count > 0) + minLevel = level; + }); + + if(ignore) + continue; + + window.plugin.guessPlayerLevels.savePlayerLevel(nickname, minLevel, certain); + } } window.plugin.guessPlayerLevels.extractChatData = function(data) { - data.raw.result.forEach(function(msg) { - var plext = msg[2].plext; - if(plext.plextType == 'SYSTEM_BROADCAST' - && plext.markup.length==5 - && plext.markup[0][0] == 'PLAYER' - && plext.markup[1][0] == 'TEXT' - && plext.markup[1][1].plain == ' deployed an ' - && plext.markup[2][0] == 'TEXT' - && plext.markup[2][0] == 'TEXT' - && plext.markup[3][0] == 'TEXT' - && plext.markup[3][1].plain == ' Resonator on ') { - var nick = plext.markup[0][1].plain; - var lvl = parseInt(plext.markup[2][1].plain.substr(1)); - window.plugin.guessPlayerLevels.savePlayerLevel(nick, lvl, true); - } - }); + data.raw.result.forEach(function(msg) { + var plext = msg[2].plext; + if(plext.plextType == 'SYSTEM_BROADCAST' + && plext.markup.length==5 + && plext.markup[0][0] == 'PLAYER' + && plext.markup[1][0] == 'TEXT' + && plext.markup[1][1].plain == ' deployed an ' + && plext.markup[2][0] == 'TEXT' + && plext.markup[2][0] == 'TEXT' + && plext.markup[3][0] == 'TEXT' + && plext.markup[3][1].plain == ' Resonator on ') { + var nick = plext.markup[0][1].plain; + var lvl = parseInt(plext.markup[2][1].plain.substr(1)); + window.plugin.guessPlayerLevels.savePlayerLevel(nick, lvl, true); + } + }); }; -window.plugin.guessPlayerLevels.savePlayerLevel = function(nick, level, safe) { +window.plugin.guessPlayerLevels.savePlayerLevel = function(nick, level, certain) { var cache = window.plugin.guessPlayerLevels._loadLevels(); var details = cache['#' + nick]; @@ -177,7 +205,7 @@ window.plugin.guessPlayerLevels.savePlayerLevel = function(nick, level, safe) { if(typeof details === 'number') details = {min: 1, guessed: details}; - if(safe) { + if(certain) { if(details.min >= level) return; @@ -317,7 +345,7 @@ window.plugin.guessPlayerLevels.sort = function(playerHash) { var setup = function() { - // we used to sture level guesses as one localStorage key per player, named 'level-PLAYER_GUID' + // we used to store level guesses as one localStorage key per player, named 'level-PLAYER_GUID' // they're now stored in a single storage key - 'plugin-guess-player-levels' - so clear these old entries $.each(Object.keys(localStorage), function(ind,key) {// legacy code - should be removed in the future if(key.lastIndexOf('level-',0)===0) { diff --git a/plugins/iitc-ditigal-bumper-sticker.user.js b/plugins/iitc-ditigal-bumper-sticker.user.js new file mode 100644 index 00000000..489e39ae --- /dev/null +++ b/plugins/iitc-ditigal-bumper-sticker.user.js @@ -0,0 +1,29 @@ +// ==UserScript== +// @id iitc-digital-bumper-sticker +// @name IITC Digital Bumper Sticker +// @category Stock +// @version 0.1.1.@@DATETIMEVERSION@@ +// @namespace https://github.com/jonatkins/ingress-intel-total-conversion +// @updateURL @@UPDATEURL@@ +// @downloadURL @@DOWNLOADURL@@ +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Adds a "I'd rather be using IITC" logo to the standard intel map. +// @include https://www.ingress.com/intel* +// @include http://www.ingress.com/intel* +// @match https://www.ingress.com/intel* +// @match http://www.ingress.com/intel* +// @grant none +// ==/UserScript== + +var targetContainer = document.getElementById('dashboard_container'); +if (targetContainer) { + + var logoDiv = document.createElement('div'); + logoDiv.setAttribute('style', "position: fixed; left: 20px; top: 130px; z-index: auto; pointer-events: none;"); + + var img = document.createElement('img'); + img.setAttribute('src', 'http://iitc.jonatkins.com/assets/img/prefer-iitc-200.png'); + + logoDiv.appendChild(img); + + targetContainer.appendChild(logoDiv); +} diff --git a/plugins/ipas-link.user.js b/plugins/ipas-link.user.js index 06352f63..6fcb4b8f 100644 --- a/plugins/ipas-link.user.js +++ b/plugins/ipas-link.user.js @@ -1,15 +1,114 @@ // ==UserScript== // @id iitc-plugin-ipas-link@graphracer // @name IITC Plugin: simulate an attack on portal -// @category Deleted -// @version 0.2.0.@@DATETIMEVERSION@@ +// @category Portal Info +// @version 0.2.1.@@DATETIMEVERSION@@ // @namespace https://github.com/xosofox/IPAS // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description PLUGIN CURRENTLY UNAVAILABLE +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Add a link to the portal details to open the portal in IPAS - Ingress Portal Attack Simulator on http://ipas.graphracer.com. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* // @match http://www.ingress.com/intel* // @grant none // ==/UserScript== + +@@PLUGINSTART@@ + +// PLUGIN START //////////////////////////////////////////////////////// + +// use own namespace for plugin +window.plugin.ipasLink = function() {}; + +window.plugin.ipasLink.setupCallback = function() { + addHook('portalDetailsUpdated', window.plugin.ipasLink.addLink); +} + +window.plugin.ipasLink.addLink = function(p) { + $('.linkdetails').append(''); +} + +window.plugin.ipasLink.getHash = function (p) { + var details = p.portalDetails; + + var hashParts = []; + $.each(details.resonatorArray.resonators, function (ind, reso) { + if (reso) + hashParts.push(reso.level + "," + reso.distanceToPortal + "," + reso.energyTotal); + else + hashParts.push("1,20,0"); + }); + var resos = hashParts.join(";"); + + hashParts = []; + $.each(details.portalV2.linkedModArray, function (ind, mod) { + // s - shields + // h - heat sink + // i - intentionally left in + // t - turret + // + // f - force amp + // m - multi-hack + // l - link-amp + // + var modCodes = { + "RES_SHIELD": "s", + "HEATSINK": "h", + "TURRET": "t", + "FORCE_AMP": "f", + "MULTIHACK": "m", + "LINK_AMPLIFIER": "l" + } + + var mc = "0"; + if (mod) { + if (mod.type in modCodes) { + mc = modCodes[mod.type] + mod.rarity.charAt(0).toLowerCase(); + + //special for shields to distinguish old/new mitigation + if (mod.type == "RES_SHIELD") + mc += mod.stats.MITIGATION; + } + } + hashParts.push(mc); + }); + var shields = hashParts.join(","); + + var linkParts = []; + var portalLL = p.portal.getLatLng(); + var edges = getPortalLinks(p.guid); + edges["in"].forEach(function (guid) { + //calc distance in m here + var distance = 1; //default to 1m, so a low level portal would support it + + //Try to find other portals details + var o = window.portals[guid]; + if (o) + distance = Math.round(portalLL.distanceTo(o.getLatLng())); + + linkParts.push(distance); + }); + edges["out"].forEach(function (guid) { + //calc distance in m here + var distance = 1; //default to 1m, so a low level portal would support it + + //Try to find other portals details + var o = window.portals[guid]; + if (o) + distance = Math.round(portalLL.distanceTo(o.getLatLng())); + + linkParts.push(-distance); // "-" to mark outgoing links + }); + var links = linkParts.join(","); + + return resos + "/" + shields + "/" + links; //changed with IPAS 1.1 to / instead of | +} + +var setup = function () { + window.plugin.ipasLink.setupCallback(); +} + +// PLUGIN END ////////////////////////////////////////////////////////// + +@@PLUGINEND@@ diff --git a/plugins/keys-on-map.user.js b/plugins/keys-on-map.user.js index 094b806c..4bb8270e 100644 --- a/plugins/keys-on-map.user.js +++ b/plugins/keys-on-map.user.js @@ -6,7 +6,7 @@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Show the manually entered key counts from keys plugin on the map. +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Show the manually entered key counts from the 'keys' plugin on the map. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* diff --git a/plugins/keys.user.js b/plugins/keys.user.js index 7ba1697b..70575748 100644 --- a/plugins/keys.user.js +++ b/plugins/keys.user.js @@ -6,7 +6,7 @@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Allow manual entry of key counts for each portal. Use 'keys-on-map' to show the numbers on the map, and 'sync' to share between multiple browsers or desktop/mobile. +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Allow manual entry of key counts for each portal. Use the 'keys-on-map' plugin to show the numbers on the map, and 'sync' to share between multiple browsers or desktop/mobile. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* @@ -155,7 +155,7 @@ window.plugin.keys.loadLocal = function(mapping) { : JSON.parse(objectJSON); } -// For backward compitable, will change to use loadLocal after a few version +// For backward compatibility, will change to use loadLocal after a few version window.plugin.keys.loadKeys = function() { var keysObjectJSON = localStorage[plugin.keys.KEY.key]; if(!keysObjectJSON) return; diff --git a/plugins/layer-farms-find.user.js b/plugins/layer-farms-find.user.js index 33eccbc2..fcee25ad 100644 --- a/plugins/layer-farms-find.user.js +++ b/plugins/layer-farms-find.user.js @@ -6,7 +6,7 @@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Find farms by minimum level +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Find farms by minimum level. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* diff --git a/plugins/link-show-direction.user.js b/plugins/link-show-direction.user.js index f5f087e6..446991fc 100644 --- a/plugins/link-show-direction.user.js +++ b/plugins/link-show-direction.user.js @@ -6,7 +6,7 @@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Show the direction of links on the map, by adding short dashes to the line at the origin portal. +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Show the direction of links on the map by adding short dashes to the line at the origin portal. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* diff --git a/plugins/max-links.user.js b/plugins/max-links.user.js index 944d2c00..6c46c070 100644 --- a/plugins/max-links.user.js +++ b/plugins/max-links.user.js @@ -5,7 +5,7 @@ // @version 0.4.2.@@DATETIMEVERSION@@ // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Calculates how to link the portals to create a reasonably tidy set of links/fields. Enable from the layer chooser. (Max Links is a poor name, but remains for historical reasons.) +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Calculate how to link the portals to create a reasonably tidy set of links/fields. Enable from the layer chooser. (Max Links is a poor name, but remains for historical reasons.) // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* diff --git a/plugins/minimap.user.js b/plugins/minimap.user.js index d8c49cda..691aece2 100644 --- a/plugins/minimap.user.js +++ b/plugins/minimap.user.js @@ -6,7 +6,7 @@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Shows a mini map on the corner of the map +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Show a mini map on the corner of the map. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* @@ -41,17 +41,17 @@ window.plugin.miniMap.setup = function() { var mqMapOpt = {attribution: osmAttribution+', Tiles Courtesy of MapQuest', maxZoom: 18, subdomains: mqSubdomains}; var mqMap = new L.TileLayer(mqTileUrlPrefix+'/tiles/1.0.0/map/{z}/{x}/{y}.jpg',mqMapOpt); - if(!isSmartphone()) { - // desktop mode - bottom-left, so it doesn't clash with the sidebar - new L.Control.MiniMap(mqMap, {toggleDisplay: true, position: 'bottomleft'}).addTo(window.map); - } else { - // mobile mode - bottom-right - so it floats above the map copyright text - new L.Control.MiniMap(mqMap, {toggleDisplay: true, position: 'bottomright'}).addTo(window.map); - } + setTimeout(function() { + if(!isSmartphone()) { + // desktop mode - bottom-left, so it doesn't clash with the sidebar + new L.Control.MiniMap(mqMap, {toggleDisplay: true, position: 'bottomleft'}).addTo(window.map); + } else { + // mobile mode - bottom-right - so it floats above the map copyright text + new L.Control.MiniMap(mqMap, {toggleDisplay: true, position: 'bottomright'}).addTo(window.map); + } + }, 0); $('head').append(''); - - }; var setup = window.plugin.miniMap.setup; diff --git a/plugins/pan-control.user.js b/plugins/pan-control.user.js index 7e9788cc..1e1ca84e 100644 --- a/plugins/pan-control.user.js +++ b/plugins/pan-control.user.js @@ -6,7 +6,7 @@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Shows a panning control on the map +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Shows a panning control on the map. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* @@ -26,10 +26,16 @@ window.plugin.panControl.setup = function() { try { console.log('Loading Leaflet.Pancontrol JS now'); } catch(e) {} @@INCLUDERAW:external/L.Control.Pan.js@@ try { console.log('done loading Leaflet.Pancontrol JS'); } catch(e) {} - + + // prevent Pancontrol from being activated by default (e.g. in minimap) + L.Map.mergeOptions({ + panControl: false + }); + + window.map.panControl = L.control.pan({panOffset: 350}); window.map.addControl(window.map.panControl); - + if(map.zoomControl._map) { // Move above the zoom control window.map.removeControl(map.zoomControl); window.map.zoomControl = L.control.zoom(); diff --git a/plugins/player-tracker.user.js b/plugins/player-tracker.user.js index 20d7cd46..ece79b0a 100644 --- a/plugins/player-tracker.user.js +++ b/plugins/player-tracker.user.js @@ -6,7 +6,7 @@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Draws trails for the path a user went onto the map based on status messages in COMMs. Draws up to three hours. Does not request chat data on its own, even if that would be useful. +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Draw trails for the path a user took onto the map based on status messages in COMMs. Uses up to three hours of data. Does not request chat data on its own, even if that would be useful. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* diff --git a/plugins/portal-counts.user.js b/plugins/portal-counts.user.js index 07f92162..63a83d1d 100644 --- a/plugins/portal-counts.user.js +++ b/plugins/portal-counts.user.js @@ -2,11 +2,11 @@ // @id iitc-plugin-portals-count@yenky // @name IITC plugin: Show total counts of portals // @category Info -// @version 0.0.9.@@DATETIMEVERSION@@ +// @version 0.1.0.@@DATETIMEVERSION@@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Display a list of all localized portals by level and faction +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Display a list of all localized portals by level and faction. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* @@ -19,95 +19,303 @@ // PLUGIN START //////////////////////////////////////////////////////// /* whatsnew -* 0.0.8 : use dialog() instead of alert() -* 0.0.6 : ignoring outside bounds portals (even if close to) -* 0.0.5 : changed table layout, added some colors -* 0.0.4 : reverse show order of portals, using MAX_PORTAL_LEVEL now for array, changed table layout to be more compact, cleaned up code -* 0.0.3 : fixed incorrect rounded portal levels, adjusted viewport -* 0.0.2 : fixed counts to be reset after scrolling -* 0.0.1 : initial release, show count of portals -* todo : -*/ +* 0.1.0 : display graphs +* 0.0.10 : show in nav drawer on mobile devices +* 0.0.9 : fix for new intel map +* 0.0.8 : use dialog() instead of alert() +* 0.0.6 : ignoring outside bounds portals (even if close to) +* 0.0.5 : changed table layout, added some colors +* 0.0.4 : reverse show order of portals, using MAX_PORTAL_LEVEL now for array, changed table layout to be more compact, cleaned up code +* 0.0.3 : fixed incorrect rounded portal levels, adjusted viewport +* 0.0.2 : fixed counts to be reset after scrolling +* 0.0.1 : initial release, show count of portals +*/ // use own namespace for plugin -window.plugin.portalcounts = function() {}; +window.plugin.portalcounts = { + BAR_TOP: 20, + BAR_HEIGHT: 180, + BAR_WIDTH: 25, + BAR_PADDING: 5, + RADIUS_INNER: 70, + RADIUS_OUTER: 100, + CENTER_X: 200, + CENTER_Y: 100, +}; //count portals for each level available on the map -window.plugin.portalcounts.getPortals = function(){ +window.plugin.portalcounts.getPortals = function (){ //console.log('** getPortals'); - var retval=false; + var self = window.plugin.portalcounts; var displayBounds = map.getBounds(); - window.plugin.portalcounts.enlP = 0; - window.plugin.portalcounts.resP = 0; - window.plugin.portalcounts.neuP = 0; - - window.plugin.portalcounts.PortalsEnl = new Array(); - window.plugin.portalcounts.PortalsRes = new Array(); + self.enlP = 0; + self.resP = 0; + self.neuP = 0; + + self.PortalsEnl = new Array(); + self.PortalsRes = new Array(); for(var level = window.MAX_PORTAL_LEVEL; level > 0; level--){ - window.plugin.portalcounts.PortalsEnl[level] = 0; - window.plugin.portalcounts.PortalsRes[level] = 0; + self.PortalsEnl[level] = 0; + self.PortalsRes[level] = 0; } - + $.each(window.portals, function(i, portal) { - retval=true; var level = portal.options.level; var team = portal.options.team; // just count portals in viewport if(!displayBounds.contains(portal.getLatLng())) return true; switch (team){ case 1 : - window.plugin.portalcounts.resP++; - window.plugin.portalcounts.PortalsRes[level]++; + self.resP++; + self.PortalsRes[level]++; break; case 2 : - window.plugin.portalcounts.enlP++; - window.plugin.portalcounts.PortalsEnl[level]++; + self.enlP++; + self.PortalsEnl[level]++; break; default: - window.plugin.portalcounts.neuP++; + self.neuP++; break; } }); - + //get portals informations from IITC var minlvl = getMinPortalLevel(); + var total = self.neuP + self.enlP + self.resP; - var counts = ''; - if(retval) { - counts += ''; //'+window.plugin.portalcounts.enlP+' Portal(s)'; + var counts = ''; + if(total > 0) { + counts += '
EnlightenedResistance
'; //'+self.enlP+' Portal(s)'; for(var level = window.MAX_PORTAL_LEVEL; level > 0; level--){ counts += ''; if(minlvl > level) counts += ''; else - counts += ''; + counts += ''; counts += ''; } - counts += ''; + counts += ''; counts += ''; + counts += self.neuP; + counts += '
EnlightenedResistance
Level '+level+'zoom in to see portals in this level'+window.plugin.portalcounts.PortalsEnl[level]+''+window.plugin.portalcounts.PortalsRes[level]+''+self.PortalsEnl[level]+''+self.PortalsRes[level]+'
Total:'+window.plugin.portalcounts.enlP+''+window.plugin.portalcounts.resP+'
Total:'+self.enlP+''+self.resP+'
Neutral:'; if(minlvl > 0) counts += 'zoom in to see unclaimed portals'; else - counts += window.plugin.portalcounts.neuP; - counts += '
'; + var svg = $('').css("margin-top", 10); + + var all = self.PortalsRes.map(function(val,i){return val+self.PortalsEnl[i]}); + all[0] = self.neuP; + + // bar graphs + self.makeBar(self.PortalsEnl, "Enl", COLORS[2], 0 ).appendTo(svg); + self.makeBar(all , "All", "#FFFFFF", 1*(self.BAR_WIDTH + self.BAR_PADDING)).appendTo(svg); + self.makeBar(self.PortalsRes, "Res", COLORS[1], 2*(self.BAR_WIDTH + self.BAR_PADDING)).appendTo(svg); + + // pie graph + var g = $("") + .attr("transform", self.format("translate(%s,%s)", self.CENTER_X, self.CENTER_Y)) + .appendTo(svg); + + // inner parts - factions + self.makePie(0, self.resP/total, COLORS[1]).appendTo(g); + self.makePie(self.resP/total, (self.neuP + self.resP)/total, COLORS[0]).appendTo(g); + self.makePie((self.neuP + self.resP)/total, 1, COLORS[2]).appendTo(g); + + // outer part - levels + var angle = 0; + for(var i=self.PortalsRes.length-1;i>=0;i--) { + if(!self.PortalsRes[i]) + continue; + + var diff = self.PortalsRes[i] / total; + self.makeRing(angle, angle+diff, COLORS_LVL[i]).appendTo(g); + angle += diff; + } + + var diff = self.neuP / total; + self.makeRing(angle, angle+diff, COLORS_LVL[0]).appendTo(g); + angle += diff; + + for(var i=0;i") + .attr({ + x1: self.resP") + .attr({ + x1: self.resP").append(svg).html(); } else - counts += '
No Portals in range!
'; - counts += ''; + counts += '

No Portals in range!

'; + var total = self.enlP + self.resP + self.neuP; + var title = total + ' ' + (total == 1 ? 'portal' : 'portals'); - var total = window.plugin.portalcounts.enlP + window.plugin.portalcounts.resP + window.plugin.portalcounts.neuP; - dialog({ - html: '
' + counts + '
', - title: 'Portal counts: ' + total + ' ' + (total == 1 ? 'portal' : 'portals'), - }); + if(window.useAndroidPanes()) { + $('
' + + '
' + title + '
' + + counts + + '
').appendTo(document.body); + } else { + dialog({ + html: '
' + counts + '
', + title: 'Portal counts: ' + title, + width: 'auto' + }); + } } +window.plugin.portalcounts.makeBar = function(portals, text, color, shift) { + var self = window.plugin.portalcounts; + var g = $("").attr("transform", "translate("+shift+",0)"); + var sum = portals.reduce(function(a,b){ return a+b }); + var top = self.BAR_TOP; + + if(sum != 0) { + for(var i=portals.length-1;i>=0;i--) { + if(!portals[i]) + continue; + var height = self.BAR_HEIGHT * portals[i] / sum; + $("") + .attr({ + x: 0, + y: top, + width: self.BAR_WIDTH, + height: height, + fill: COLORS_LVL[i] + }) + .appendTo(g); + top += height; + } + } + + $('') + .html(text) + .attr({ + x: self.BAR_WIDTH * 0.5, + y: self.BAR_TOP * 0.75, + fill: color, + "text-anchor": "middle" + }) + .appendTo(g); + + return g; +}; + +window.plugin.portalcounts.makePie = function(startAngle, endAngle, color) { + var self = window.plugin.portalcounts; + var large_arc = (endAngle - startAngle) > 0.5 ? 1 : 0; + + startAngle = 0.5 - startAngle; + endAngle = 0.5 - endAngle; + + var p1x = Math.sin(startAngle * 2 * Math.PI) * self.RADIUS_INNER; + var p1y = Math.cos(startAngle * 2 * Math.PI) * self.RADIUS_INNER; + var p2x = Math.sin(endAngle * 2 * Math.PI) * self.RADIUS_INNER; + var p2y = Math.cos(endAngle * 2 * Math.PI) * self.RADIUS_INNER; + + // for a full circle, both coordinates would be identical, so no circle would be drawn + if(startAngle == 0.5 && endAngle == -0.5) + p2x -= 1E-5; + + return $("") + .attr({ + fill: color, + d: self.format("M %s,%s A %s,%s 0 %s 1 %s,%s L 0,0 z", p1x,p1y, self.RADIUS_INNER,self.RADIUS_INNER, large_arc, p2x,p2y) + }); +}; + +window.plugin.portalcounts.makeRing = function(startAngle, endAngle, color) { + var self = window.plugin.portalcounts; + var large_arc = (endAngle - startAngle) > 0.5 ? 1 : 0; + + startAngle = 0.5 - startAngle; + endAngle = 0.5 - endAngle; + + var p1x = Math.sin(startAngle * 2 * Math.PI) * self.RADIUS_OUTER; + var p1y = Math.cos(startAngle * 2 * Math.PI) * self.RADIUS_OUTER; + var p2x = Math.sin(endAngle * 2 * Math.PI) * self.RADIUS_OUTER; + var p2y = Math.cos(endAngle * 2 * Math.PI) * self.RADIUS_OUTER; + var p3x = Math.sin(endAngle * 2 * Math.PI) * self.RADIUS_INNER; + var p3y = Math.cos(endAngle * 2 * Math.PI) * self.RADIUS_INNER; + var p4x = Math.sin(startAngle * 2 * Math.PI) * self.RADIUS_INNER; + var p4y = Math.cos(startAngle * 2 * Math.PI) * self.RADIUS_INNER; + + // for a full circle, both coordinates would be identical, so no circle would be drawn + if(startAngle == 0.5 && endAngle == -0.5) { + p2x -= 1E-5; + p3x -= 1E-5; + } + + return $("") + .attr({ + fill: color, + d: self.format("M %s,%s ", p1x, p1y) + + self.format("A %s,%s 0 %s 1 %s,%s ", self.RADIUS_OUTER,self.RADIUS_OUTER, large_arc, p2x,p2y) + + self.format("L %s,%s ", p3x,p3y) + + self.format("A %s,%s 0 %s 0 %s,%s ", self.RADIUS_INNER,self.RADIUS_INNER, large_arc, p4x,p4y) + + "Z" + }); +}; + +window.plugin.portalcounts.format = function(str) { + var re = /%s/; + for(var i = 1; i < arguments.length; i++) { + str = str.replace(re, arguments[i]); + } + return str; +} + +window.plugin.portalcounts.onPaneChanged = function(pane) { + if(pane == "plugin-portalcounts") + window.plugin.portalcounts.getPortals(); + else + $("#portalcounts").remove() +}; + var setup = function() { - $('#toolbox').append(' Portal counts'); - $('head').append(''); diff --git a/plugins/portal-highlighter-forgotten.user.js b/plugins/portal-highlighter-forgotten.user.js index 72d8281b..50f5d44e 100644 --- a/plugins/portal-highlighter-forgotten.user.js +++ b/plugins/portal-highlighter-forgotten.user.js @@ -6,7 +6,7 @@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Highlight unclaimed portals with no recent activity. Shades of red from one week to one month, then tinted to purple for longer. (May also highlight captured portals that are stuck and fail to decay every 24 hours) +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Highlight unclaimed portals with no recent activity. Shades of red from one week to one month, then tinted to purple for longer. May also highlight captured portals that are stuck and fail to decay every 24 hours. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* diff --git a/plugins/portal-highlighter-hide-team.user.js b/plugins/portal-highlighter-hide-team.user.js index 7cfab35b..0145e5e0 100644 --- a/plugins/portal-highlighter-hide-team.user.js +++ b/plugins/portal-highlighter-hide-team.user.js @@ -6,7 +6,7 @@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Show all portals as neutral, as if uncaptured. Great for creating plans +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Show all portals as neutral, as if uncaptured. Great for creating plans. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* diff --git a/plugins/portal-highlighter-infrastructure.user.js b/plugins/portal-highlighter-infrastructure.user.js index 0a59ed53..c44e9f39 100644 --- a/plugins/portal-highlighter-infrastructure.user.js +++ b/plugins/portal-highlighter-infrastructure.user.js @@ -6,7 +6,7 @@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Red - No Picture, Yellow - Potential title issue, Orange - both of these +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Red - No Picture, Yellow - Potential title issue, Orange - both of these. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* diff --git a/plugins/portal-highlighter-level-color.user.js b/plugins/portal-highlighter-level-color.user.js index 5118fd77..ba877e25 100644 --- a/plugins/portal-highlighter-level-color.user.js +++ b/plugins/portal-highlighter-level-color.user.js @@ -6,7 +6,7 @@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill color of the portals level color. +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Use the fill color of the portals to denote portal level by using the game level colors. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* diff --git a/plugins/portal-highlighter-missing-resonators.user.js b/plugins/portal-highlighter-missing-resonators.user.js index 8788467a..77740ef4 100644 --- a/plugins/portal-highlighter-missing-resonators.user.js +++ b/plugins/portal-highlighter-missing-resonators.user.js @@ -6,7 +6,7 @@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill color of the portals to denote if the portal is missing resonators. +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Use the fill color of the portals to denote if the portal is missing resonators. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* diff --git a/plugins/portal-highlighter-needs-recharge.user.js b/plugins/portal-highlighter-needs-recharge.user.js index 0991627c..fa767f49 100644 --- a/plugins/portal-highlighter-needs-recharge.user.js +++ b/plugins/portal-highlighter-needs-recharge.user.js @@ -6,7 +6,7 @@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill color of the portals to denote if the portal needs recharging. Colours also indicate severity: yellow: above 85%, orange: above 50%, red: above 15%, magenta: below 15% +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Use the fill color of the portals to denote if the portal needs recharging. Colors also indicate severity: yellow: above 85%, orange: above 50%, red: above 15%, magenta: below 15%. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* diff --git a/plugins/portal-highlighter-portals-my-level.user.js b/plugins/portal-highlighter-portals-my-level.user.js index fe87ebeb..4ac89b48 100644 --- a/plugins/portal-highlighter-portals-my-level.user.js +++ b/plugins/portal-highlighter-portals-my-level.user.js @@ -6,7 +6,7 @@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill color of the portals above or below your level +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Uses the fill color of the portals above or below your level. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* diff --git a/plugins/portal-names.user.js b/plugins/portal-names.user.js index a1f140a9..fdc68b7c 100644 --- a/plugins/portal-names.user.js +++ b/plugins/portal-names.user.js @@ -6,7 +6,7 @@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Show portal names on the map +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Show portal names on the map. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* diff --git a/plugins/portals-list.user.js b/plugins/portals-list.user.js index 88bb636b..05cbec98 100644 --- a/plugins/portals-list.user.js +++ b/plugins/portals-list.user.js @@ -1,15 +1,317 @@ // ==UserScript== // @id iitc-plugin-portals-list@teo96 // @name IITC plugin: show list of portals -// @category Deleted -// @version 0.0.18.@@DATETIMEVERSION@@ +// @category Info +// @version 0.1.0.@@DATETIMEVERSION@@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description PLUGIN CURRENTLY UNAVAILABLE +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Display a sortable list of all visible portals with full details about the team, resonators, links, etc. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* // @match http://www.ingress.com/intel* // @grant none // ==/UserScript== + +@@PLUGINSTART@@ + +// PLUGIN START //////////////////////////////////////////////////////// + + /* whatsnew + * 0.1.0 : Using the new data format + * 0.0.15: Add 'age' column to display how long each portal has been controlled by its current owner. + * 0.0.14: Add support to new mods (S:Shield - T:Turret - LA:Link Amp - H:Heat-sink - M:Multi-hack - FA:Force Amp) + * 0.0.12: Use dialog() instead of alert so the user can drag the box around + * 0.0.11: Add nominal energy column and # links, fix sort bug when opened even amounts of times, nits + * 0.0.10: Fixed persistent css problem with alert + * 0.0.9 : bugs hunt + * 0.0.8 : Aborted to avoid problems with Niantic (export portals informations as csv or kml file) + * 0.0.7 : more informations available via tooltips (who deployed, energy, ...), new E/AP column + * 0.0.6 : Add power charge information into a new column + bugfix + * 0.0.5 : Filter portals by clicking on 'All portals', 'Res Portals' or 'Enl Portals' + * 0.0.4 : Add link to portals name, one click to display full information in portal panel, double click to zoom on portal, hover to show address + * 0.0.3 : sorting ascending/descending and add numbers of portals by faction on top on table + * 0.0.2 : add sorting feature when click on header column + * 0.0.1 : initial release, show list of portals with level, team, resonators and shield information + * + * Display code inspired from @vita10gy's scoreboard plugin : iitc-plugin-scoreboard@vita10gy - https://github.com/breunigs/ingress-intel-total-conversion + * Portal link code from xelio - iitc: AP List - https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/ap-list.user.js + * + * todo : export as GPX, Open in Google Maps, more statistics in the header, what else ? + */ + +// use own namespace for plugin +window.plugin.portalslist = function() {}; + +window.plugin.portalslist.listPortals = []; +window.plugin.portalslist.sortBy = 'level'; +window.plugin.portalslist.sortOrder = -1; +window.plugin.portalslist.enlP = 0; +window.plugin.portalslist.resP = 0; +window.plugin.portalslist.filter = 0; + +//fill the listPortals array with portals avaliable on the map (level filtered portals will not appear in the table) +window.plugin.portalslist.getPortals = function() { + //filter : 0 = All, 1 = Res, 2 = Enl + var retval=false; + + var displayBounds = map.getBounds(); + + window.plugin.portalslist.listPortals = []; + $.each(window.portals, function(i, portal) { + // eliminate offscreen portals (selected, and in padding) + if(!displayBounds.contains(portal.getLatLng())) return true; + + retval=true; + var d = portal.options.data; + var teamN = portal.options.team; + + switch (teamN) { + case TEAM_RES: + window.plugin.portalslist.resP++; + break; + case TEAM_ENL: + window.plugin.portalslist.enlP++; + break; + } + var l = window.getPortalLinks(i); + var f = window.getPortalFields(i); + var ap = portalApGainMaths(d.resCount, l.in.length+l.out.length, f.length); + + var thisPortal = { + 'portal': portal, + 'guid': i, + 'teamN': teamN, // TEAM_NONE, TEAM_RES or TEAM_ENL + 'team': d.team, // "NEUTRAL", "RESISTANCE" or "ENLIGHTENED" + 'name': d.title, + 'nameLower': d.title.toLowerCase(), + 'level': portal.options.level, + 'health': d.health, + 'resCount': d.resCount, + 'img': d.img, + 'linkCount': l.in.length + l.out.length, + 'link' : l, + 'fieldCount': f.length, + 'field' : f, + 'enemyAp': ap.enemyAp, + 'ap': ap, + }; + window.plugin.portalslist.listPortals.push(thisPortal); + }); + + return retval; +} + +window.plugin.portalslist.displayPL = function() { + var html = ''; + window.plugin.portalslist.sortBy = 'level'; + window.plugin.portalslist.sortOrder = -1; + window.plugin.portalslist.enlP = 0; + window.plugin.portalslist.resP = 0; + window.plugin.portalslist.filter = 0; + + if (window.plugin.portalslist.getPortals()) { + html += window.plugin.portalslist.portalTable(window.plugin.portalslist.sortBy, window.plugin.portalslist.sortOrder,window.plugin.portalslist.filter); + } else { + html = '
Nothing to show!
'; + }; + + if(window.useAndroidPanes()) { + $('
' + html + '
').appendTo(document.body); + } else { + dialog({ + html: '
' + html + '
', + dialogClass: 'ui-dialog-portalslist', + title: 'Portal list: ' + window.plugin.portalslist.listPortals.length + ' ' + (window.plugin.portalslist.listPortals.length == 1 ? 'portal' : 'portals'), + id: 'portal-list', + width: 700 + }); + } +} + +window.plugin.portalslist.portalTable = function(sortBy, sortOrder, filter) { + // save the sortBy/sortOrder/filter + window.plugin.portalslist.sortBy = sortBy; + window.plugin.portalslist.sortOrder = sortOrder; + window.plugin.portalslist.filter = filter; + + var portals=window.plugin.portalslist.listPortals; + + //Array sort + window.plugin.portalslist.listPortals.sort(function(a, b) { + var retVal = 0; + + var aComp = a[sortBy]; + var bComp = b[sortBy]; + + if (aComp < bComp) { + retVal = -1; + } else if (aComp > bComp) { + retVal = 1; + } else { + // equal - compare GUIDs to ensure consistant (but arbitary) order + retVal = a.guid < b.guid ? -1 : 1; + } + + // sortOrder is 1 (normal) or -1 (reversed) + retVal = retVal * sortOrder; + return retVal; + }); + + var sortAttr = window.plugin.portalslist.portalTableHeaderSortAttr; + var html = window.plugin.portalslist.stats(); + html += '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '\n'; + + var rowNum = 1; + + $.each(portals, function(ind, portal) { + if (filter === TEAM_NONE || filter === portal.teamN) { + + html += '' + + '' + + '' + + '' + + ''; + + html += '' + + '' + + '' + + ''; + + var apTitle = ''; + if (PLAYER.team == portal.team) { + apTitle += 'Friendly AP:\t'+portal.ap.friendlyAp+'\n' + + '- deploy '+(8-portal.resCount)+' resonator(s)\n' + + '- upgrades/mods unknown\n'; + } + apTitle += 'Enemy AP:\t'+portal.ap.enemyAp+'\n' + + '- Destroy AP:\t'+portal.ap.destroyAp+'\n' + + '- Capture AP:\t'+portal.ap.captureAp; + + html += ''; + + html+= ''; + + rowNum++; + } + }); + html += '
#Portal NameLevelTeamHealthResLinksFieldsAP
'+rowNum+'' + window.plugin.portalslist.getPortalLink(portal, portal.guid) + '' + portal.level + '' + portal.team.substr(0,3) + '' + (portal.teamN!=TEAM_NONE?portal.health+'%':'-') + '' + portal.resCount + '' + (portal.linkCount?portal.linkCount:'-') + '' + (portal.fieldCount?portal.fieldCount:'-') + '' + digits(portal.ap.enemyAp) + '
'; + + html += '
Click on portals table headers to sort by that column. ' + + 'Click on All Portals, Resistance Portals, Enlightened Portals to filter
'; + + return html; +} + +window.plugin.portalslist.stats = function(sortBy) { + var html = '' + + '' + + '' + + '' + + '' + + '
All Portals : (click to filter)' + window.plugin.portalslist.listPortals.length + 'Resistance Portals : ' + window.plugin.portalslist.resP +' (' + Math.floor(window.plugin.portalslist.resP/window.plugin.portalslist.listPortals.length*100) + '%)Enlightened Portals : '+ window.plugin.portalslist.enlP +' (' + Math.floor(window.plugin.portalslist.enlP/window.plugin.portalslist.listPortals.length*100) + '%)
'; + return html; +} + +// A little helper function so the above isn't so messy +window.plugin.portalslist.portalTableHeaderSortAttr = function(name, by, defOrder, extraClass) { + // data-sort attr: used by jquery .data('sort') below + var retVal = 'data-sort="'+name+'" data-defaultorder="'+defOrder+'" class="'+(extraClass?extraClass+' ':'')+'sortable'+(name==by?' sorted':'')+'"'; + + return retVal; +}; + +// portal link - single click: select portal +// double click: zoom to and select portal +// hover: show address +// code from getPortalLink function by xelio from iitc: AP List - https://raw.github.com/breunigs/ingress-intel-total-conversion/gh-pages/plugins/ap-list.user.js +window.plugin.portalslist.getPortalLink = function(portal,guid) { + var coord = portal.portal.getLatLng(); + var latlng = [coord.lat, coord.lng].join(); + var jsSingleClick = 'window.renderPortalDetails(\''+guid+'\');return false'; + var jsDoubleClick = 'window.zoomToAndShowPortal(\''+guid+'\', ['+latlng+']);return false'; + var perma = '/intel?latE6='+coord.lat+'&lngE6='+coord.lng+'&z=17&pguid='+guid; + + //Use Jquery to create the link, which escape characters in TITLE and ADDRESS of portal + var a = $('',{ + text: portal.name, + title: portal.name, + href: perma, + onClick: jsSingleClick, + onDblClick: jsDoubleClick + })[0].outerHTML; + + return a; +} + +window.plugin.portalslist.onPaneChanged = function(pane) { + if(pane == "plugin-portalslist") + window.plugin.portalslist.displayPL(); + else + $("#portalslist").remove() +}; + +var setup = function() { + if(window.useAndroidPanes()) { + android.addPane("plugin-portalslist", "Portals list", "ic_action_paste"); + addHook("paneChanged", window.plugin.portalslist.onPaneChanged); + } else { + $('#toolbox').append(' Portals list'); + } + + $('head').append(''); + + // Setup sorting + $(document).on('click.portalslist', '#portalslist table th.sortable', function() { + var sortBy = $(this).data('sort'); + // if this is the currently selected column, toggle the sort order - otherwise use the columns default sort order + var sortOrder = sortBy == window.plugin.portalslist.sortBy ? window.plugin.portalslist.sortOrder*-1 : parseInt($(this).data('defaultorder')); + $('#portalslist').html(window.plugin.portalslist.portalTable(sortBy,sortOrder,window.plugin.portalslist.filter)); + }); + + $(document).on('click.portalslist', '#portalslist .filterAll', function() { + $('#portalslist').html(window.plugin.portalslist.portalTable(window.plugin.portalslist.sortBy,window.plugin.portalslist.sortOrder,0)); + }); + $(document).on('click.portalslist', '#portalslist .filterRes', function() { + $('#portalslist').html(window.plugin.portalslist.portalTable(window.plugin.portalslist.sortBy,window.plugin.portalslist.sortOrder,1)); + }); + $(document).on('click.portalslist', '#portalslist .filterEnl', function() { + $('#portalslist').html(window.plugin.portalslist.portalTable(window.plugin.portalslist.sortBy,window.plugin.portalslist.sortOrder,2)); + }); +} + +// PLUGIN END ////////////////////////////////////////////////////////// + +@@PLUGINEND@@ diff --git a/plugins/privacy-view.user.js b/plugins/privacy-view.user.js index 92daeede..8f7fcd91 100644 --- a/plugins/privacy-view.user.js +++ b/plugins/privacy-view.user.js @@ -3,7 +3,7 @@ // @name IITC plugin: Privacy view on Intel // @version 1.0.0.@@DATETIMEVERSION@@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion -// @description [@@BUILDNAME@@-@@BUILDDATE@@] From Intel hides info which shouldn't leak to players of other fraction +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Hide info from intel which shouldn't leak to players of the other faction. // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ // @include https://www.ingress.com/intel* diff --git a/plugins/reso-energy-pct-in-portal-detail.user.js b/plugins/reso-energy-pct-in-portal-detail.user.js index 1120167c..aa6ecbf7 100644 --- a/plugins/reso-energy-pct-in-portal-detail.user.js +++ b/plugins/reso-energy-pct-in-portal-detail.user.js @@ -22,20 +22,20 @@ window.plugin.resoEnergyPctInPortalDetal = function() {}; window.plugin.resoEnergyPctInPortalDetal.updateMeter = function(data) { - var meterLevel = $("span.meter-level"); - meterLevel - .css('top','0px') - .css('left','5px') - .css('margin-left','0px') - .css('font-size','80%') - .css('line-height','18px'); - meterLevel.each(function() { - var matchResult = $(this).parent().attr('title').match(/\((\d*\%)\)/); - if(matchResult) { - var newMeterContent = 'L' + $(this).html() + '  ' + matchResult[1]; - $(this).html(newMeterContent); - } - }); + $("span.meter-level") + .css({ + "word-spacing": "-1px", + "text-align": "left", + "font-size": "90%", + "padding-left": "2px", + }) + .each(function() { + var matchResult = $(this).parent().attr('title').match(/\((\d*\%)\)/); + if(matchResult) { + var html = $(this).html() + '
' + matchResult[1] + '
'; + $(this).html(html); + } + }); } var setup = function() { diff --git a/plugins/scale-bar.user.js b/plugins/scale-bar.user.js index 26830c75..e30cb0b4 100644 --- a/plugins/scale-bar.user.js +++ b/plugins/scale-bar.user.js @@ -6,7 +6,7 @@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Shows scale bar on the map +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Shows scale bar on the map. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* diff --git a/plugins/show-less-portals-zoomed-out.user.js b/plugins/show-less-portals-zoomed-out.user.js index ddace55d..c18ae0c2 100644 --- a/plugins/show-less-portals-zoomed-out.user.js +++ b/plugins/show-less-portals-zoomed-out.user.js @@ -6,7 +6,7 @@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] IITC now defaults to showing fewer portals when zoomed out, making this plugin unnecessary +// @description [@@BUILDNAME@@-@@BUILDDATE@@] IITC now defaults to showing fewer portals when zoomed out, making this plugin unnecessary. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* diff --git a/plugins/show-linked-portals.user.js b/plugins/show-linked-portals.user.js index 8a7679a3..b8427d1f 100644 --- a/plugins/show-linked-portals.user.js +++ b/plugins/show-linked-portals.user.js @@ -6,7 +6,7 @@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Tries to show the linked portals (image, name and address) in portal detail view and jump to linked portal on click +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Try to show the linked portals (image, name and link direction) in portal detail view and jump to linked portal on click. Some details may not be available if the linked portal is not in the current view. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* @@ -74,17 +74,17 @@ window.plugin.showLinkedPortal.getPortalByGuid = function (guid,isorigin) { if (window.portals[guid] !== undefined) { var portalData = window.portals[guid].options.data; - var portalNameAdressAlt = "'" + portalData.title + "'";; - var portalNameAdressTitle = $('
').append($('').text(portalData.title)) - .append($('
')) - .append(linkDirection) - .html(); + var portalNameAddressAlt = "'" + portalData.title + "'";; + var portalNameAddressTitle = $('
').append($('').text(portalData.title)) + .append($('
')) + .append(linkDirection) + .html(); var imageUrl = fixPortalImageUrl(portalData.image); portalInfoString = $('
').html($('').attr('src', imageUrl) .attr('class', 'minImg') - .attr('alt', portalNameAdressAlt) - .attr('title', portalNameAdressTitle)) - .html(); + .attr('alt', portalNameAddressAlt) + .attr('title', portalNameAddressTitle)) + .html(); } else { var title = $('
').append($('').text('Go to portal')) .append($('
')) diff --git a/plugins/speech-search.user.js b/plugins/speech-search.user.js index 589f785c..5bb63e06 100644 --- a/plugins/speech-search.user.js +++ b/plugins/speech-search.user.js @@ -5,7 +5,7 @@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Allow speech input for location search (webkit only for now - NOT Firefox) +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Allow speech input for location search (webkit only for now - NOT Firefox). // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* diff --git a/plugins/zoom-slider.user.js b/plugins/zoom-slider.user.js index d54e4be0..dc93c182 100644 --- a/plugins/zoom-slider.user.js +++ b/plugins/zoom-slider.user.js @@ -6,7 +6,7 @@ // @namespace https://github.com/jonatkins/ingress-intel-total-conversion // @updateURL @@UPDATEURL@@ // @downloadURL @@DOWNLOADURL@@ -// @description [@@BUILDNAME@@-@@BUILDDATE@@] Shows a zoom slider on the map instead of the zoom buttons +// @description [@@BUILDNAME@@-@@BUILDDATE@@] Show a zoom slider on the map instead of the zoom buttons. // @include https://www.ingress.com/intel* // @include http://www.ingress.com/intel* // @match https://www.ingress.com/intel* @@ -27,6 +27,11 @@ window.plugin.zoomSlider.setup = function() { @@INCLUDERAW:external/L.Control.Zoomslider.js@@ try { console.log('done loading Leaflet.zoomslider JS'); } catch(e) {} + // prevent Zoomslider from being activated by default (e.g. in minimap) + L.Map.mergeOptions({ + zoomsliderControl: false + }); + if(map.zoomControl._map) { window.map.removeControl(map.zoomControl); } @@ -35,7 +40,7 @@ window.plugin.zoomSlider.setup = function() { $('head').append(''); }; -var setup = window.plugin.zoomSlider.setup; +var setup = window.plugin.zoomSlider.setup; // PLUGIN END ////////////////////////////////////////////////////////// diff --git a/style.css b/style.css index 4dffc9fa..df690235 100644 --- a/style.css +++ b/style.css @@ -650,6 +650,23 @@ h3 { top: 0; } +.meter.north { + overflow: hidden; +} +.meter.north:before { + content: ""; + background-color: red; + border: 1px solid #000000; + border-radius: 100%; + display: block; + height: 6px; + width: 6px; + left: 50%; + top: -3px; + margin-left: -4px; + position: absolute; +} + .meter span { display: block; height: 14px; @@ -657,10 +674,12 @@ h3 { .meter-level { position: absolute; + left: 0; + right: 0; top: -2px; - left: 50%; - margin-left: -6px; text-shadow: 0.0em 0.0em 0.3em #808080; + text-align: center; + word-spacing: 4px; /* to leave some space for the north indicator */ } /* links below resos */ diff --git a/website/assets/css/style.css b/website/assets/css/style.css index 8c4cc1e0..d5a882e3 100644 --- a/website/assets/css/style.css +++ b/website/assets/css/style.css @@ -11,3 +11,17 @@ table tr.category_header { table .description { font-style: italic; } + +.icon-chevron-desktop, +.icon-chevron-mobile { + background-image: url("../img/glyphicons-devices.png"); + background-position: 0 0; +} +.nav-list > .active > a > .icon-chevron-desktop, +.nav-list > .active > a > .icon-chevron-mobile +{ + background-image: url("../img/glyphicons-devices-white.png"); +} +.icon-chevron-mobile { + background-position: 0 -14px; +} diff --git a/website/assets/img/glyphicons-devices-white.png b/website/assets/img/glyphicons-devices-white.png new file mode 100644 index 00000000..0493b329 Binary files /dev/null and b/website/assets/img/glyphicons-devices-white.png differ diff --git a/website/assets/img/glyphicons-devices.png b/website/assets/img/glyphicons-devices.png new file mode 100644 index 00000000..3f0df69b Binary files /dev/null and b/website/assets/img/glyphicons-devices.png differ diff --git a/website/assets/img/prefer-iitc-200.png b/website/assets/img/prefer-iitc-200.png new file mode 100644 index 00000000..3732c76f Binary files /dev/null and b/website/assets/img/prefer-iitc-200.png differ diff --git a/website/assets/img/prefer-iitc-205.png b/website/assets/img/prefer-iitc-205.png new file mode 100644 index 00000000..657ccb77 Binary files /dev/null and b/website/assets/img/prefer-iitc-205.png differ diff --git a/website/assets/img/prefer-iitc-256.png b/website/assets/img/prefer-iitc-256.png new file mode 100644 index 00000000..21b36023 Binary files /dev/null and b/website/assets/img/prefer-iitc-256.png differ diff --git a/website/assets/img/prefer-iitc-512.png b/website/assets/img/prefer-iitc-512.png new file mode 100644 index 00000000..5c6dc047 Binary files /dev/null and b/website/assets/img/prefer-iitc-512.png differ diff --git a/website/index.php b/website/index.php index 43e61f2a..1902cc16 100644 --- a/website/index.php +++ b/website/index.php @@ -102,8 +102,8 @@ $pages = Array ( 'home' => ' Home', 'news' => ' News', 'faq' => ' FAQ', - 'desktop' => ' Desktop', - 'mobile' => ' Mobile', + 'desktop' => ' Desktop', + 'mobile' => ' Mobile', 'test' => ' Test Builds', 'developer' => ' Developers', 'about' => ' About', diff --git a/website/page/faq.php b/website/page/faq.php index 4374caa1..72754750 100644 --- a/website/page/faq.php +++ b/website/page/faq.php @@ -2,23 +2,6 @@
    -
  • -

    Login on mobile doesn't work!

    -

    -Many users are seeing the error message Error: Server Error when attempting to log in on mobile. -To get past this and log in successfully, you can try to -

      -
    1. Exit IITC and try again. Some people have success after a number of tries, or
    2. -
    3. Cancel when asked to choose an account, and manually enter your email address and password into the web page
    4. -
    -

    -

    -As far as we can tell this isn't an IITC Mobile issue - using the Chrome browser on android, which also supports -Google login, can give similar issues. Further discussion on this is happening in -github issue #497. -

    -
  • -
  • I get a message saying my account isn't activated

    @@ -26,7 +9,7 @@ Occasionally the Niantic servers give this misleading message - what it should u "Failed to check account status - please reload to try again". IITC will, in most cases, retry for you.

    -Sometimes this is caused by server issues, and no ammount of reloading will fix it. Come back later and try again. +Sometimes this is caused by server issues, and no amount of reloading will fix it. Come back later and try again.

    However, another reason for this message is your account being blocked/suspended by Niantic. There diff --git a/website/page/home.php b/website/page/home.php index 3c26342d..c39dffda 100644 --- a/website/page/home.php +++ b/website/page/home.php @@ -13,7 +13,33 @@ offers many more features. It is available for

    Latest news

    -
    +

    6th December 2013

    +

    +Niantic have just released a minor update to the standard intel site. Good news - recent IITC changes have made it +successfully detect the protocol changes in most cases, so no update is needed. You may need to reload the page, +and for IITC Mobile you may need to change a cache setting. See +this G+ post for more details. +

    + +

    2nd December 2013

    +

    +IITC 0.16.0 and IITC Mobile 0.10.0 have been released. This update is required to work with the latest changes to +the standard intel site. This update took a fair amount of work due to major changes +in the network protocol used behind the standard intel website, hence the longer than usual delay for the update. +

    +

    +As well as IITC itself, nearly every single plugin broke in some way due to these changes. Due to the amount of work +needed to get everything possible working again, some plugins have been disabled for now. You can see the list of these +disabled plugins in the download list - they're in the 'Deleted' category with a description of 'PLUGIN CURRENTLY UNAVAILABLE'. +

    +

    +Shortly after the Niantic changes that broke IITC, there were reports of IITC users being banned. This seemed strange at +first, as IITC was not even functioning at this time, so why would people be using it and getting banned. The conclusion +that was reached was that a few people who tried to use the broken IITC Mobile app triggered either a bug in IITC that +caused excessive requests, or triggered some kind of alert in the intel servers. Changes have been made to IITC now +so this unlikely to be an issue again. +

    +

    27th November 2013

    IITC and IITC Mobile are currently broken, due to changes made to the standard intel website. This is a major change in how @@ -36,60 +62,5 @@ More details, and discussion, available in the This is shown as version 0.15.99. When a fixed build is released, it will be 0.16.something and will update and start working. Test versions remain, but broken. Please join the Google+ Community where announcements will be made.

    -
    - -

    11th November 2013

    -

    -IITC 0.15.0 and IITC Mobile 0.9 have just been released. This update fixes things to work with the latest changes -to the standard intel site. Also -

      -
    • Support for Jarvis shards (and other future artifacts)
    • -
    • New base map plugins - for maps.stamen.com/ and Bing maps.
    • -
    -

    - -

    7th November 2013

    -

    -IITC 0.14.6 and IITC Mobile 0.7.7.2 released. Another change needed to match a minor update to the standard intel site. -

    - -

    6th November 2013

    -

    -IITC 0.14.5 and IITC Mobile 0.7.7.1 have been released. This contains a fix to work with the latest intel site updates. -Other than this, it is identical to the 0.14.4/0.7.7 release. -

    - -

    29th October 2013

    -

    -IITC 0.14.4 and IITC Mobile 0.7.7 have just been released. A critical update required to work with changes made to the -standard intel site. Changes include -

      -
    • Fix to geodesic circle drawing. They were not correctly distorted, leading to incorrect link ranges drawn on the map.
    • -
    • Bookmarks plugin: add layer and highlighter to indicate bookmarked portals
    • -
    • Player tracker plugin: markers fade for older activity, and separate layers for each faction
    • -
    • The 'About IITC' dialog now lists which plugins are installed. This may not work correctly for 3rd party plugins at this time
    • -
    • Mobile: -
        -
      • Custom fullscreen preferences
      • -
      • Install to SD Card
      • -
      • Cache move to SD card option (hence the new permissions)
      • -
      -
    • -
    • ... and, as always, various bugfixes and improvements.
    • -
    -

    -

    -3RD PARTY PLUGIN AUTHORS: The plugin wrapper code has been modified to pass through the additional version -information. While existing plugins should continue to work, I highly recommend updating the wrapper code in your -scripts to match. -

    - -

    16th October 2013

    -

    -IITC 0.14.3 and IITC Mobile 0.7.4 have just been released. This is a critical update required to work with the latest -changes Niantic have made to the standard intel site. Additionally, the draw-tools plugin now snaps points to portals -when creating lines/polygons/markers (was actually in 0.14.2 release), a bugfix relating to IITC not realising who -'you' are, causing some highlighters to break, and a handful of other tweaks/bugfixes. -

    Older news diff --git a/website/page/mobile.php b/website/page/mobile.php index 35198d6b..7093a8bd 100644 --- a/website/page/mobile.php +++ b/website/page/mobile.php @@ -24,12 +24,11 @@ install from the link below.

    Known issues

    -IITC Mobile is still in the early stages of development. Many things do not yet work right. Major known issues are: +IITC Mobile has some known problems, major issues are:

      -
    1. Some users get Error: Server Error when logging in. See the FAQ for possible workarounds.
    2. -
    3. Some plugins do not work well, or at all, at this time.
    4. -
    5. Serious issues exist on Android 4.0 devices. -details.
    6. +
    7. Some plugins do not work well, or at all.
    8. +
    9. Pinch zoom hangs on some devices. +details.

    diff --git a/website/page/news.php b/website/page/news.php index 59b1b381..ec3aaf9a 100644 --- a/website/page/news.php +++ b/website/page/news.php @@ -1,6 +1,32 @@

    News

    -
    +

    6th December 2013

    +

    +Niantic have just released a minor update to the standard intel site. Good news - recent IITC changes have made it +successfully detect the protocol changes in most cases, so no update is needed. You may need to reload the page, +and for IITC Mobile you may need to change a cache setting. See +this G+ post for more details. +

    + +

    2nd December 2013

    +

    +IITC 0.16.0 and IITC Mobile 0.10.0 have been released. This update is required to work with the latest changes to +the standard intel site. This update took a fair amount of work due to major changes +in the network protocol used behind the standard intel website, hence the longer than usual delay for the update. +

    +

    +As well as IITC itself, nearly every single plugin broke in some way due to these changes. Due to the amount of work +needed to get everything possible working again, some plugins have been disabled for now. You can see the list of these +disabled plugins in the download list - they're in the 'Deleted' category with a description of 'PLUGIN CURRENTLY UNAVAILABLE'. +

    +

    +Shortly after the Niantic changes that broke IITC, there were reports of IITC users being banned. This seemed strange at +first, as IITC was not even functioning at this time, so why would people be using it and getting banned. The conclusion +that was reached was that a few people who tried to use the broken IITC Mobile app triggered either a bug in IITC that +caused excessive requests, or triggered some kind of alert in the intel servers. Changes have been made to IITC now +so this unlikely to be an issue again. +

    +

    27th November 2013

    IITC and IITC Mobile are currently broken, due to changes made to the standard intel website. This is a major change in how @@ -23,7 +49,6 @@ More details, and discussion, available in the This is shown as version 0.15.99. When a fixed build is released, it will be 0.16.something and will update and start working. Test versions remain, but broken. Please join the Google+ Community where announcements will be made.

    -

    11th November 2013