PageSourceSearch

https://www.aist-ev.de/assets/js/c7e18375f110.js

js aist-ev.de collected 2026-10-05 01:47:11 UTC 601,966 bytes, 13,980 lines download raw bytes

vendor: 4,491 bytes, lines 1-2
1/*! jQuery v1.12.4 | (c) jQuery Foundation | jquery.org/license */
2!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="1.12.4",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(n.isPlainObject(c)||(b=n.isArray(c)))?(b?(b=!1,f=a&&n.isArray(a)?a:[]):f=a&&n.isPlainObject(a)?a:{},g[d]=n.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray||function(a){return"array"===n.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==n.type(a)||a.nodeType||n.isWindow(a))return!1;try{if(a.constructor&&!k.call(a,"constructor")&&!k.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(!l.ownFirst)for(b in a)return k.call(a,b);for(b in a);return void 0===b||k.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(b){b&&n.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(h)return h.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(f=a[b],b=a,a=f),n.isFunction(a)?(c=e.call(arguments,2),d=function(){return a.apply(b||this,c.concat(e.call(arguments)))},d.guid=a.guid=a.guid||n.guid++,d):void 0},now:function(){return+new Date},support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*ne
vendor: 3,069 bytes, line 2
2w Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+N+")*)|.*)\\)|)",P=new RegExp(L+"+","g"),Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(O),V=new RegExp("^"+M+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,aa=/'|\\/g,ba=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ca=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(aa,"\\$&"):b.setAttribute("id",k=u),r=g(a),h=r.length,l=V.test(k)?"#"+k:"[id='"+k+"']";while(h--)r[h]=l+" "+qa(r[h]);s=r.join(","),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(Q,"$1"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ha(a){return a[u]=!0,a}
vendor: 9,959 bytes, line 2
2function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ia(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\r\\' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ia(function(a){var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",O)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Z.test(o.compareDocumentPosition),t=b||Z.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fa.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fa.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fa.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fa.selectors={cacheLength:50,createPseudo:ha,match:W,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ba,ca),a[3]=(a[3]||a[4]||a[5]||"").replace(ba,ca),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fa.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&U.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ba,ca).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fa.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(P," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,"$1"));return d[u]?ha(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||"")||fa.error("unsupported lang: "+a),a=a.replace(ba,ca).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)}
vendor: 79,644 bytes, lines 2-5
2,input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=la(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=ma(b);function pa(){}pa.prototype=d.filters=d.pseudos,d.setFilters=new pa,g=fa.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){c&&!(e=R.exec(h))||(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=S.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(Q," ")}),h=h.slice(c.length));for(g in d.filter)!(e=W[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?fa.error(a):z(a,i).slice(0)};function qa(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(c&&!c(f,d,e)||(g.push(f),j&&b.push(h)));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(Q,"$1"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ia(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ja("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ja("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute("disabled")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,y=/^.[^:#\[\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return n.inArray(a,b)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;e>b;b++)if(n.contains(d[b],this))return!0}));for(b=0;e>b;b++)n.find(a,d[b],c);return c=this.pushStack(e>1?n.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,"string"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,"string"==typeof a){if(e="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}if(f=d.getElementById(e[2]),f&&f.parentNode){if(f.id!==e[2])return A.find(a);this.length=1,this[0]=f}return this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b,c=n(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(n.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?n.inArray(this[0],n(a)):n.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,"parentNode")},parentsUntil:function(a,b,c){return u(a,"parentNode",c)},next:function(a){return F(a,"nextSibling")},prev:function(a){return F(a,"previousSibling")},nextAll:function(a){return u(a,"nextSibling")},prevAll:function(a){return u(a,"previousSibling")},nextUntil:function(a,b,c){return u(a,"nextSibling",c)},prevUntil:function(a,b,c){return u(a,"previousSibling",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return n.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||(e=n.uniqueSort(e)),D.test(a)&&(e=e.reverse())),this.pushStack(e)}});var G=/\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:"")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){n.each(b,function(b,c){n.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&"string"!==n.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return n.each(arguments,function(a,b){var c;while((c=n.inArray(b,f,c))>-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=!0,c||j.disable(),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler("ready"),n(d).off("ready"))))}});function J(){d.addEventListener?(d.removeEventListener("DOMContentLoaded",K),a.removeEventListener("load",K)):(d.detachEvent("onreadystatechange",K),a.detachEvent("onload",K))}function K(){(d.addEventListener||"load"===a.event.type||"complete"===d.readyState)&&(J(),n.ready())}n.ready.promise=function(b){if(!I)if(I=n.Deferred(),"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll)a.setTimeout(n.ready);else if(d.addEventListener)d.addEventListener("DOMContentLoaded",K),a.addEventListener("load",K);else{d.attachEvent("onreadystatechange",K),a.attachEvent("onload",K);var c=!1;try{c=null==a.frameElement&&d.documentElement}catch(e){}c&&c.doScroll&&!function f(){if(!n.isReady){try{c.doScroll("left")}catch(b){return a.setTimeout(f,50)}J(),n.ready()}}()}return I.promise(b)},n.ready.promise();var L;for(L in n(l))break;l.ownFirst="0"===L,l.inlineBlockNeedsLayout=!1,n(function(){var a,b,c,e;c=d.getElementsByTagName("body")[0],c&&c.style&&(b=d.createElement("div"),e=d.createElement("div"),e.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(e).appendChild(b),"undefined"!=typeof b.style.zoom&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",l.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(e))}),function(){var a=d.createElement("div");l.deleteExpando=!0;try{delete a.test}catch(b){l.deleteExpando=!1}a=null}();var M=function(a){var b=n.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b},N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(O,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}n.data(a,b,c)}else c=void 0;
3}return c}function Q(a){var b;for(b in a)if(("data"!==b||!n.isEmptyObject(a[b]))&&"toJSON"!==b)return!1;return!0}function R(a,b,d,e){if(M(a)){var f,g,h=n.expando,i=a.nodeType,j=i?n.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||n.guid++:h),j[k]||(j[k]=i?{}:{toJSON:n.noop}),"object"!=typeof b&&"function"!=typeof b||(e?j[k]=n.extend(j[k],b):j[k].data=n.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[n.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[n.camelCase(b)])):f=g,f}}function S(a,b,c){if(M(a)){var d,e,f=a.nodeType,g=f?n.cache:a,h=f?a[n.expando]:n.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){n.isArray(b)?b=b.concat(n.map(b,n.camelCase)):b in d?b=[b]:(b=n.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!Q(d):!n.isEmptyObject(d))return}(c||(delete g[h].data,Q(g[h])))&&(f?n.cleanData([a],!0):l.deleteExpando||g!=g.window?delete g[h]:g[h]=void 0)}}}n.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?n.cache[a[n.expando]]:a[n.expando],!!a&&!Q(a)},data:function(a,b,c){return R(a,b,c)},removeData:function(a,b){return S(a,b)},_data:function(a,b,c){return R(a,b,c,!0)},_removeData:function(a,b){return S(a,b,!0)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=n.data(f),1===f.nodeType&&!n._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));n._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){n.data(this,a)}):arguments.length>1?this.each(function(){n.data(this,a,b)}):f?P(f,a,n.data(f,a)):void 0},removeData:function(a){return this.each(function(){n.removeData(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=n._data(a,b),c&&(!d||n.isArray(c)?d=n._data(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return n._data(a,c)||n._data(a,c,{empty:n.Callbacks("once memory").add(function(){n._removeData(a,b+"queue"),n._removeData(a,c)})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=n._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}}),function(){var a;l.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,e;return c=d.getElementsByTagName("body")[0],c&&c.style?(b=d.createElement("div"),e=d.createElement("div"),e.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(e).appendChild(b),"undefined"!=typeof b.style.zoom&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(d.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(e),a):void 0}}();var T=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,U=new RegExp("^(?:([+-])=|)("+T+")([a-z%]*)$","i"),V=["Top","Right","Bottom","Left"],W=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)};function X(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return n.css(a,b,"")},i=h(),j=c&&c[3]||(n.cssNumber[b]?"":"px"),k=(n.cssNumber[b]||"px"!==j&&+i)&&U.exec(n.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,n.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var Y=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)Y(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},Z=/^(?:checkbox|radio)$/i,$=/<([\w:-]+)/,_=/^$|\/(?:java|ecma)script/i,aa=/^\s+/,ba="abbr|article|aside|audio|bdi|canvas|data|datalist|details|dialog|figcaption|figure|footer|header|hgroup|main|mark|meter|nav|output|picture|progress|section|summary|template|time|video";function ca(a){var b=ba.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}!function(){var a=d.createElement("div"),b=d.createDocumentFragment(),c=d.createElement("input");a.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",l.leadingWhitespace=3===a.firstChild.nodeType,l.tbody=!a.getElementsByTagName("tbody").length,l.htmlSerialize=!!a.getElementsByTagName("link").length,l.html5Clone="<:nav></:nav>"!==d.createElement("nav").cloneNode(!0).outerHTML,c.type="checkbox",c.checked=!0,b.appendChild(c),l.appendChecked=c.checked,a.innerHTML="<textarea>x</textarea>",l.noCloneChecked=!!a.cloneNode(!0).lastChild.defaultValue,b.appendChild(a),c=d.createElement("input"),c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),a.appendChild(c),l.checkClone=a.cloneNode(!0).cloneNode(!0).lastChild.checked,l.noCloneEvent=!!a.addEventListener,a[n.expando]=1,l.attributes=!a.getAttribute(n.expando)}();var da={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:l.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]};da.optgroup=da.option,da.tbody=da.tfoot=da.colgroup=da.caption=da.thead,da.th=da.td;function ea(a,b){var c,d,e=0,f="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||n.nodeName(d,b)?f.push(d):n.merge(f,ea(d,b));return void 0===b||b&&n.nodeName(a,b)?n.merge([a],f):f}function fa(a,b){for(var c,d=0;null!=(c=a[d]);d++)n._data(c,"globalEval",!b||n._data(b[d],"globalEval"))}var ga=/<|&#?\w+;/,ha=/<tbody/i;function ia(a){Z.test(a.type)&&(a.defaultChecked=a.checked)}function ja(a,b,c,d,e){for(var f,g,h,i,j,k,m,o=a.length,p=ca(b),q=[],r=0;o>r;r++)if(g=a[r],g||0===g)if("object"===n.type(g))n.merge(q,g.nodeType?[g]:g);else if(ga.test(g)){i=i||p.appendChild(b.createElement("div")),j=($.exec(g)||["",""])[1].toLowerCase(),m=da[j]||da._default,i.innerHTML=m[1]+n.htmlPrefilter(g)+m[2],f=m[0];while(f--)i=i.lastChild;if(!l.leadingWhitespace&&aa.test(g)&&q.push(b.createTextNode(aa.exec(g)[0])),!l.tbody){g="table"!==j||ha.test(g)?"<table>"!==m[1]||ha.test(g)?0:i:i.firstChild,f=g&&g.childNodes.length;while(f--)n.nodeName(k=g.childNodes[f],"tbody")&&!k.childNodes.length&&g.removeChild(k)}n.merge(q,i.childNodes),i.textContent="";while(i.firstChild)i.removeChild(i.firstChild);i=p.lastChild}else q.push(b.createTextNode(g));i&&p.removeChild(i),l.appendChecked||n.grep(ea(q,"input"),ia),r=0;while(g=q[r++])if(d&&n.inArray(g,d)>-1)e&&e.push(g);else if(h=n.contains(g.ownerDocument,g),i=ea(p.appendChild(g),"script"),h&&fa(i),c){f=0;while(g=i[f++])_.test(g.type||"")&&c.push(g)}return i=null,p}!function(){var b,c,e=d.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(l[b]=c in a)||(e.setAttribute(c,"t"),l[b]=e.attributes[c].expando===!1);e=null}();var ka=/^(?:input|select|textarea)$/i,la=/^key/,ma=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,na=/^(?:focusinfocus|focusoutblur)$/,oa=/^([^.]*)(?:\.(.+)|)/;function pa(){return!0}function qa(){return!1}function ra(){try{return d.activeElement}catch(a){}}function sa(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)sa(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=qa;else if(!e)return a;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=n.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return"undefined"==typeof n||a&&n.event.triggered===a.type?void 0:n.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(G)||[""],h=b.length;while(h--)f=oa.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=n.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=n.event.special[o]||{},l=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},i),(m=g[o])||(m=g[o]=[],m.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,l):m.push(l),n.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=n.hasData(a)&&n._data(a);if(r&&(k=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=oa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=m.length;while(f--)g=m[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(m.splice(f,1),g.selector&&m.delegateCount--,l.remove&&l.remove.call(a,g));i&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(k)&&(delete r.handle,n._removeData(a,"events"))}},trigger:function(b,c,e,f){var g,h,i,j,l,m,o,p=[e||d],q=k.call(b,"type")?b.type:b,r=k.call(b,"namespace")?b.namespace.split("."):[];if(i=m=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!na.test(q+n.event.triggered)&&(q.indexOf(".")>-1&&(r=q.split("."),q=r.shift(),r.sort()),h=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=r.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:n.makeArray(c,[b]),l=n.event.special[q]||{},f||!l.trigger||l.trigger.apply(e,c)!==!1)){if(!f&&!l.noBubble&&!n.isWindow(e)){for(j=l.delegateType||q,na.test(j+q)||(i=i.parentNode);i;i=i.parentNode)p.push(i),m=i;m===(e.ownerDocument||d)&&p.push(m.defaultView||m.parentWindow||a)}o=0;while((i=p[o++])&&!b.isPropagationStopped())b.type=o>1?j:l.bindType||q,g=(n._data(i,"events")||{})[b.type]&&n._data(i,"handle"),g&&g.apply(i,c),g=h&&i[h],g&&g.apply&&M(i)&&(b.result=g.apply(i,c),b.result===!1&&b.preventDefault());if(b.type=q,!f&&!b.isDefaultPrevented()&&(!l._default||l._default.apply(p.pop(),c)===!1)&&M(e)&&h&&e[q]&&!n.isWindow(e)){m=e[h],m&&(e[h]=null),n.event.triggered=q;try{e[q]()}catch(s){}n.event.triggered=void 0,m&&(e[h]=m)}return b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(n._data(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())a.rnamespace&&!a.rnamespace.test(g.namespace)||(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[n.expando])return a;var b,c,e,f=a.type,g=a,h=this.fixHooks[f];h||(this.fixHooks[f]=h=ma.test(f)?this.mouseHooks:la.test(f)?this.keyHooks:{}),e=h.props?this.props.concat(h.props):this.props,a=new n.Event(g),b=e.length;while(b--)c=e[b],a[c]=g[c];return a.target||(a.target=g.srcElement||d),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,h.filter?h.filter(a,g):a},props:"altKey bubbles cancelable ctrlKey currentTarget detail eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,e,f,g=b.button,h=b.fromElement;return null==a.pageX&&null!=b.clientX&&(e=a.target.ownerDocument||d,f=e.documentElement,c=e.body,a.pageX=b.clientX+(f&&f.scrollLeft||c&&c.scrollLeft||0)-(f&&f.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(f&&f.scrollTop||c&&c.scrollTop||0)-(f&&f.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&h&&(a.relatedTarget=h===a.target?b.toElement:h),a.which||void 0===g||(a.which=1&g?1:2&g?3:4&g?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==ra()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:"focusin"},blur:{trigger:function(){return this===ra()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return n.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c){var d=n.extend(new n.Event,c,{type:a,isSimulated:!0});n.event.trigger(d,null,b),d.isDefaultPrevented()&&c.preventDefault()}},n.removeEvent=d.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)}:function(a,b,c){var d="on"+b;a.detachEvent&&("undefined"==typeof a[d]&&(a[d]=null),a.detachEvent(d,c))},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?pa:qa):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={constructor:n.Event,isDefaultPrevented:qa,isPropagationStopped:qa,isImmediatePropagationStopped:qa,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=pa,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=pa,a&&!this.isSimulated&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=pa,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},n.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return e&&(e===d||n.contains(d,e))||(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),l.submit||(n.event.special.submit={setup:function(){return n.nodeName(this,"form")?!1:void n.event.add(this,"click._submit keypress._submit",function(a){var b=a.target,c=n.nodeName(b,"input")||n.nodeName(b,"button")?n.prop(b,"form"):void 0;c&&!n._data(c,"submit")&&(n.event.add(c,"submit._submit",function(a){a._submitBubble=!0}),n._data(c,"submit",!0))})},postDispatch:function(a){a._submitBubble&&(delete a._submitBubble,this.parentNode&&!a.isTrigger&&n.event.simulate("submit",this.parentNode,a))},teardown:function(){return n.nodeName(this,"form")?!1:void n.event.remove(this,"._submit")}}),l.change||(n.event.special.change={setup:function(){return ka.test(this.nodeName)?("checkbox"!==this.type&&"radio"!==this.type||(n.event.add(this,"propertychange._change",function(a){"checked"===a.originalEvent.propertyName&&(this._justChanged=!0)}),n.event.add(this,"click._change",function(a){this._justChanged&&!a.isTrigger&&(this._justChanged=!1),n.event.simulate("change",this,a)})),!1):void n.event.add(this,"beforeactivate._change",function(a){var b=a.target;ka.test(b.nodeName)&&!n._data(b,"change")&&(n.event.add(b,"change._change",function(a){!this.parentNode||a.isSimulated||a.isTrigger||n.event.simulate("change",this.parentNode,a)}),n._data(b,"change",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||"radio"!==b.type&&"checkbox"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return n.event.remove(this,"._change"),!ka.test(this.nodeName)}}),l.focusin||n.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a))};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=n._data(d,b);e||d.addEventListener(a,c,!0),n._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=n._data(d,b)-1;e?n._data(d,b,e):(d.removeEventListener(a,c,!0),n._removeData(d,b))}}}),n.fn.extend({on:function(a,b,c,d){return sa(this,a,b,c,d)},one:function(a,b,c,d){return sa(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return b!==!1&&"function"!=typeof b||(c=b,b=void 0),c===!1&&(c=qa),this.each(function(){n.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}});var ta=/ jQuery\d+="(?:null|\d+)"/g,ua=new RegExp("<(?:"+ba+")[\\s/>]","i"),va=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,wa=/<script|<style|<link/i,xa=/checked\s*(?:[^=]|=\s*.checked.)/i,ya=/^true\/(.*)/,za=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,Aa=ca(d),Ba=Aa.appendChild(d.createElement("div"));function Ca(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function Da(a){return a.type=(null!==n.find.attr(a,"type"))+"/"+a.type,a}function Ea(a){var b=ya.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function Fa(a,b){if(1===b.nodeType&&n.hasData(a)){var c,d,e,f=n._data(a),g=n._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)n.event.add(b,c,h[c][d])}g.data&&(g.data=n.extend({},g.data))}}function Ga(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!l.noCloneEvent&&b[n.expando]){e=n._data(b);for(d in e.events)n.removeEvent(b,d,e.handle);b.removeAttribute(n.expando)}"script"===c&&b.text!==a.text?(Da(b).text=a.text,Ea(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),l.html5Clone&&a.innerHTML&&!n.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&Z.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:"input"!==c&&"textarea"!==c||(b.defaultValue=a.defaultValue)}}function Ha(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&"string"==typeof q&&!l.checkClone&&xa.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),Ha(f,b,c,d)});if(o&&(k=ja(b,a[0].ownerDocument,!1,a,d),e=k.firstChild,1===k.childNodes.length&&(k=e),e||d)){for(i=n.map(ea(k,"script"),Da),h=i.length;o>m;m++)g=k,m!==p&&(g=n.clone(g,!0,!0),h&&n.merge(i,ea(g,"script"))),c.call(a[m],g,m);if(h)for(j=i[i.length-1].ownerDocument,n.map(i,Ea),m=0;h>m;m++)g=i[m],_.test(g.type||"")&&!n._data(g,"globalEval")&&n.contains(j,g)&&(g.src?n._evalUrl&&n._evalUrl(g.src):n.globalEval((g.text||g.textContent||g.innerHTML||"").replace(za,"")));k=e=null}return a}function Ia(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(ea(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&fa(ea(d,"script")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(va,"<$1></$2>")},clone:function(a,b,c){var d,e,f,g,h,i=n.contains(a.ownerDocument,a);if(l.html5Clone||n.isXMLDoc(a)||!ua.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(Ba.innerHTML=a.outerHTML,Ba.removeChild(f=Ba.firstChild)),!(l.noCloneEvent&&l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(d=ea(f),h=ea(a),g=0;null!=(e=h[g]);++g)d[g]&&Ga(e,d[g]);if(b)if(c)for(h=h||ea(a),d=d||ea(f),g=0;null!=(e=h[g]);g++)Fa(e,d[g]);else Fa(a,f);return d=ea(f,"script"),d.length>0&&fa(d,!i&&ea(a,"script")),d=h=e=null,f},cleanData:function(a,b){for(var d,e,f,g,h=0,i=n.expando,j=n.cache,k=l.attributes,m=n.event.special;null!=(d=a[h]);h++)if((b||M(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)m[e]?n.event.remove(d,e):n.removeEvent(d,e,g.handle);j[f]&&(delete j[f],k||"undefined"==typeof d.removeAttribute?d[i]=void 0:d.removeAttribute(i),c.push(f))}}}),n.fn.extend({domManip:Ha,detach:function(a){return Ia(this,a,!0)},remove:function(a){return Ia(this,a)},text:function(a){return Y(this,function(a){return void 0===a?n.text(this):this.empty().append((this[0]&&this[0].ownerDocument||d).createTextNode(a))},null,a,arguments.length)},append:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.appendChild(a)}})},prepend:function(){return Ha(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=Ca(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return Ha(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&n.cleanData(ea(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&n.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return Y(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(ta,""):void 0;if("string"==typeof a&&!wa.test(a)&&(l.htmlSerialize||!ua.test(a))&&(l.leadingWhitespace||!aa.test(a))&&!da[($.exec(a)||["",""])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ea(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return Ha(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(ea(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=0,e=[],f=n(a),h=f.length-1;h>=d;d++)c=d===h?this:this.clone(!0),n(f[d])[b](c),g.apply(e,c.get());return this.pushStack(e)}});var Ja,Ka={HTML:"block",BODY:"block"};function La(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],"display");return c.detach(),d}function Ma(a){var b=d,c=Ka[a];return c||(c=La(a,b),"none"!==c&&c||(Ja=(Ja||n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=(Ja[0].contentWindow||Ja[0].contentDocument).document,b.write(),b.close(),c=La(a,b),Ja.detach()),Ka[a]=c),c}var Na=/^margin/,Oa=new RegExp("^("+T+")(?!px)[a-z%]+$","i"),Pa=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e},Qa=d.documentElement;!function(){var b,c,e,f,g,h,i=d.createElement("div"),j=d.createElement("div");if(j.style){j.style.cssText="float:left;opacity:.5",l.opacity="0.5"===j.style.opacity,l.cssFloat=!!j.style.cssFloat,j.style.backgroundClip="content-box",j.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===j.style.backgroundClip,i=d.createElement("div"),i.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",j.innerHTML="",i.appendChild(j),l.boxSizing=""===j.style.boxSizing||""===j.style.MozBoxSizing||""===j.style.WebkitBoxSizing,n.extend(l,{reliableHiddenOffsets:function(){return null==b&&k(),f},boxSizingReliable:function(){return null==b&&k(),e},pixelMarginRight:function(){return null==b&&k(),c},pixelPosition:function(){return null==b&&k(),b},reliableMarginRight:function(){return null==b&&k(),g},reliableMarginLeft:function(){return null==b&&k(),h}});function k(){var k,l,m=d.documentElement;m.appendChild(i),j.style.cssText="-webkit-box-sizing:border-box;box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",b=e=h=!1,c=g=!0,a.getComputedStyle&&(l=a.getComputedStyle(j),b="1%"!==(l||{}).top,h="2px"===(l||{}).marginLeft,e="4px"===(l||{width:"4px"}).width,j.style.marginRight="50%",c="4px"===(l||{marginRight:"4px"}).marginRight,k=j.appendChild(d.createElement("div")),k.style.cssText=j.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",k.style.marginRight=k.style.width="0",j.style.width="1px",g=!parseFloat((a.getComputedStyle(k)||{}).marginRight),j.removeChild(k)),j.style.display="none",f=0===j.getClientRects().length,f&&(j.style.display="",j.innerHTML="<table><tr><td></td><td>t</td></tr></table>",j.childNodes[0].style.borderCollapse="separate",k=j.getElementsByTagName("td"),k[0].style.cssText="margin:0;border:0;padding:0;display:none",f=0===k[0].offsetHeight,f&&(k[0].style.display="",k[1].style.display="none",f=0===k[0].offsetHeight)),m.removeChild(i)}}}();var Ra,Sa,Ta=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ra=function(b){var c=b.ownerDocument.defaultView;return c&&c.opener||(c=a),c.getComputedStyle(b)},Sa=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ra(a),g=c?c.getPropertyValue(b)||c[b]:void 0,""!==g&&void 0!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),c&&!l.pixelMarginRight()&&Oa.test(g)&&Na.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f),void 0===g?g:g+""}):Qa.currentStyle&&(Ra=function(a){return a.currentStyle},Sa=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ra(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Oa.test(g)&&!Ta.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Ua(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Va=/alpha\([^)]*\)/i,Wa=/opacity\s*=\s*([^)]*)/i,Xa=/^(none|table(?!-c[ea]).+)/,Ya=new RegExp("^("+T+")(.*)$","i"),Za={position:"absolute",visibility:"hidden",display:"block"},$a={letterSpacing:"0",fontWeight:"400"},_a=["Webkit","O","Moz","ms"],ab=d.createElement("div").style;function bb(a){if(a in ab)return a;var b=a.charAt(0).toUpperCase()+a.slice(1),c=_a.length;while(c--)if(a=_a[c]+b,a in ab)return a}function cb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=n._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&W(d)&&(f[g]=n._data(d,"olddisplay",Ma(d.nodeName)))):(e=W(d),(c&&"none"!==c||!e)&&n._data(d,"olddisplay",e?c:n.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function db(a,b,c){var d=Ya.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function eb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=n.css(a,c+V[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+V[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+V[f]+"Width",!0,e))):(g+=n.css(a,"padding"+V[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+V[f]+"Width",!0,e)));return g}function fb(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ra(a),g=l.boxSizing&&"border-box"===n.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Sa(a,b,f),(0>e||null==e)&&(e=a.style[b]),Oa.test(e))return e;d=g&&(l.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+eb(a,b,c||(g?"border":"content"),d,f)+"px"}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Sa(a,"opacity");return""===c?"1":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":l.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;if(b=n.cssProps[h]||(n.cssProps[h]=bb(h)||h),g=n.cssHooks[b]||n.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=U.exec(c))&&e[1]&&(c=X(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(n.cssNumber[h]?"":"px")),l.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=bb(h)||h),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Sa(a,b,d)),"normal"===f&&b in $a&&(f=$a[b]),""===c||c?(e=parseFloat(f),c===!0||isFinite(e)?e||0:f):f}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?Xa.test(n.css(a,"display"))&&0===a.offsetWidth?Pa(a,Za,function(){return fb(a,b,d)}):fb(a,b,d):void 0},set:function(a,c,d){var e=d&&Ra(a);return db(a,c,d?eb(a,b,d,l.boxSizing&&"border-box"===n.css(a,"boxSizing",!1,e),e):0)}}}),l.opacity||(n.cssHooks.opacity={get:function(a,b){return Wa.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=n.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===n.trim(f.replace(Va,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Va.test(f)?f.replace(Va,e):f+" "+e)}}),n.cssHooks.marginRight=Ua(l.reliableMarginRight,function(a,b){return b?Pa(a,{display:"inline-block"},Sa,[a,"marginRight"]):void 0}),n.cssHooks.marginLeft=Ua(l.reliableMarginLeft,function(a,b){return b?(parseFloat(Sa(a,"marginLeft"))||(n.contains(a.ownerDocument,a)?a.getBoundingClientRect().left-Pa(a,{
4marginLeft:0},function(){return a.getBoundingClientRect().left}):0))+"px":void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+V[d]+b]=f[d]||f[d-2]||f[0];return e}},Na.test(a)||(n.cssHooks[a+b].set=db)}),n.fn.extend({css:function(a,b){return Y(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=Ra(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b)},a,b,arguments.length>1)},show:function(){return cb(this,!0)},hide:function(){return cb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){W(this)?n(this).show():n(this).hide()})}});function gb(a,b,c,d,e){return new gb.prototype.init(a,b,c,d,e)}n.Tween=gb,gb.prototype={constructor:gb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||n.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=gb.propHooks[this.prop];return a&&a.get?a.get(this):gb.propHooks._default.get(this)},run:function(a){var b,c=gb.propHooks[this.prop];return this.options.duration?this.pos=b=n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):gb.propHooks._default.set(this),this}},gb.prototype.init.prototype=gb.prototype,gb.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[n.cssProps[a.prop]]&&!n.cssHooks[a.prop]?a.elem[a.prop]=a.now:n.style(a.elem,a.prop,a.now+a.unit)}}},gb.propHooks.scrollTop=gb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},n.fx=gb.prototype.init,n.fx.step={};var hb,ib,jb=/^(?:toggle|show|hide)$/,kb=/queueHooks$/;function lb(){return a.setTimeout(function(){hb=void 0}),hb=n.now()}function mb(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=V[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function nb(a,b,c){for(var d,e=(qb.tweeners[b]||[]).concat(qb.tweeners["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ob(a,b,c){var d,e,f,g,h,i,j,k,m=this,o={},p=a.style,q=a.nodeType&&W(a),r=n._data(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,m.always(function(){m.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=n.css(a,"display"),k="none"===j?n._data(a,"olddisplay")||Ma(a.nodeName):j,"inline"===k&&"none"===n.css(a,"float")&&(l.inlineBlockNeedsLayout&&"inline"!==Ma(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",l.shrinkWrapBlocks()||m.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],jb.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||n.style(a,d)}else j=void 0;if(n.isEmptyObject(o))"inline"===("none"===j?Ma(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=n._data(a,"fxshow",{}),f&&(r.hidden=!q),q?n(a).show():m.done(function(){n(a).hide()}),m.done(function(){var b;n._removeData(a,"fxshow");for(b in o)n.style(a,b,o[b])});for(d in o)g=nb(q?r[d]:0,d,m),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function pb(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function qb(a,b,c){var d,e,f=0,g=qb.prefilters.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=hb||lb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{},easing:n.easing._default},c),originalProperties:b,originalOptions:c,startTime:hb||lb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for(pb(k,j.opts.specialEasing);g>f;f++)if(d=qb.prefilters[f].call(j,a,k,j.opts))return n.isFunction(d.stop)&&(n._queueHooks(j.elem,j.opts.queue).stop=n.proxy(d.stop,d)),d;return n.map(k,nb,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(qb,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return X(c.elem,a,U.exec(b),c),c}]},tweener:function(a,b){n.isFunction(a)?(b=a,a=["*"]):a=a.match(G);for(var c,d=0,e=a.length;e>d;d++)c=a[d],qb.tweeners[c]=qb.tweeners[c]||[],qb.tweeners[c].unshift(b)},prefilters:[ob],prefilter:function(a,b){b?qb.prefilters.unshift(a):qb.prefilters.push(a)}}),n.speed=function(a,b,c){var d=a&&"object"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,null!=d.queue&&d.queue!==!0||(d.queue="fx"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(W).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=qb(this,n.extend({},a),f);(e||n._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=n.timers,g=n._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&kb.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));!b&&c||n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=n._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each(["toggle","show","hide"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(mb(b,!0),a,d,e)}}),n.each({slideDown:mb("show"),slideUp:mb("hide"),slideToggle:mb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=n.timers,c=0;for(hb=n.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||n.fx.stop(),hb=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){ib||(ib=a.setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){a.clearInterval(ib),ib=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(b,c){return b=n.fx?n.fx.speeds[b]||b:b,c=c||"fx",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a,b=d.createElement("input"),c=d.createElement("div"),e=d.createElement("select"),f=e.appendChild(d.createElement("option"));c=d.createElement("div"),c.setAttribute("className","t"),c.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",a=c.getElementsByTagName("a")[0],b.setAttribute("type","checkbox"),c.appendChild(b),a=c.getElementsByTagName("a")[0],a.style.cssText="top:1px",l.getSetAttribute="t"!==c.className,l.style=/top/.test(a.getAttribute("style")),l.hrefNormalized="/a"===a.getAttribute("href"),l.checkOn=!!b.value,l.optSelected=f.selected,l.enctype=!!d.createElement("form").enctype,e.disabled=!0,l.optDisabled=!f.disabled,b=d.createElement("input"),b.setAttribute("value",""),l.input=""===b.getAttribute("value"),b.value="t",b.setAttribute("type","radio"),l.radioValue="t"===b.value}();var rb=/\r/g,sb=/[\x20\t\r\n\f]+/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e="":"number"==typeof e?e+="":n.isArray(e)&&(e=n.map(e,function(a){return null==a?"":a+""})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(rb,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){var b=n.find.attr(a,"value");return null!=b?b:n.trim(n.text(a)).replace(sb," ")}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],(c.selected||i===e)&&(l.optDisabled?!c.disabled:null===c.getAttribute("disabled"))&&(!c.parentNode.disabled||!n.nodeName(c.parentNode,"optgroup"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)if(d=e[g],n.inArray(n.valHooks.option.get(d),f)>-1)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),n.each(["radio","checkbox"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>-1:void 0}},l.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var tb,ub,vb=n.expr.attrHandle,wb=/^(?:checked|selected)$/i,xb=l.getSetAttribute,yb=l.input;n.fn.extend({attr:function(a,b){return Y(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),e=n.attrHooks[b]||(n.expr.match.bool.test(b)?ub:tb)),void 0!==c?null===c?void n.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=n.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!l.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(G);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)?yb&&xb||!wb.test(c)?a[d]=!1:a[n.camelCase("default-"+c)]=a[d]=!1:n.attr(a,c,""),a.removeAttribute(xb?c:d)}}),ub={set:function(a,b,c){return b===!1?n.removeAttr(a,c):yb&&xb||!wb.test(c)?a.setAttribute(!xb&&n.propFix[c]||c,c):a[n.camelCase("default-"+c)]=a[c]=!0,c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=vb[b]||n.find.attr;yb&&xb||!wb.test(b)?vb[b]=function(a,b,d){var e,f;return d||(f=vb[b],vb[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,vb[b]=f),e}:vb[b]=function(a,b,c){return c?void 0:a[n.camelCase("default-"+b)]?b.toLowerCase():null}}),yb&&xb||(n.attrHooks.value={set:function(a,b,c){return n.nodeName(a,"input")?void(a.defaultValue=b):tb&&tb.set(a,b,c)}}),xb||(tb={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},vb.id=vb.name=vb.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},n.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:tb.set},n.attrHooks.contenteditable={set:function(a,b,c){tb.set(a,""===b?!1:b,c)}},n.each(["width","height"],function(a,b){n.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),l.style||(n.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var zb=/^(?:input|select|textarea|button|object)$/i,Ab=/^(?:a|area)$/i;n.fn.extend({prop:function(a,b){return Y(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return a=n.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),n.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&n.isXMLDoc(a)||(b=n.propFix[b]||b,e=n.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=n.find.attr(a,"tabindex");return b?parseInt(b,10):zb.test(a.nodeName)||Ab.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),l.hrefNormalized||n.each(["href","src"],function(a,b){n.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),l.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null},set:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this}),l.enctype||(n.propFix.enctype="encoding");var Bb=/[\t\r\n\f]/g;function Cb(a){return n.attr(a,"class")||""}n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,Cb(this)))});if("string"==typeof a&&a){b=a.match(G)||[];while(c=this[i++])if(e=Cb(c),d=1===c.nodeType&&(" "+e+" ").replace(Bb," ")){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=n.trim(d),e!==h&&n.attr(c,"class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,Cb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(G)||[];while(c=this[i++])if(e=Cb(c),d=1===c.nodeType&&(" "+e+" ").replace(Bb," ")){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=n.trim(d),e!==h&&n.attr(c,"class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):n.isFunction(a)?this.each(function(c){n(this).toggleClass(a.call(this,c,Cb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=n(this),f=a.match(G)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else void 0!==a&&"boolean"!==c||(b=Cb(this),b&&n._data(this,"__className__",b),n.attr(this,"class",b||a===!1?"":n._data(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+Cb(c)+" ").replace(Bb," ").indexOf(b)>-1)return!0;return!1}}),n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var Db=a.location,Eb=n.now(),Fb=/\?/,Gb=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;n.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=n.trim(b+"");return e&&!n.trim(e.replace(Gb,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():n.error("Invalid JSON: "+b)},n.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new a.DOMParser,c=d.parseFromString(b,"text/xml")):(c=new a.ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||n.error("Invalid XML: "+b),c};var Hb=/#.*$/,Ib=/([?&])_=[^&]*/,Jb=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Kb=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Lb=/^(?:GET|HEAD)$/,Mb=/^\/\//,Nb=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Ob={},Pb={},Qb="*/".concat("*"),Rb=Db.href,Sb=Nb.exec(Rb.toLowerCase())||[];function Tb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(G)||[];if(n.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Ub(a,b,c,d){var e={},f=a===Pb;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Vb(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&n.extend(!0,a,c),a}function Wb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Xb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:Rb,type:"GET",isLocal:Kb.test(Sb[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Qb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":n.parseJSON,"text xml":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Vb(Vb(a,n.ajaxSettings),b):Vb(n.ajaxSettings,a)},ajaxPrefilter:Tb(Ob),ajaxTransport:Tb(Pb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var d,e,f,g,h,i,j,k,l=n.ajaxSetup({},c),m=l.context||l,o=l.context&&(m.nodeType||m.jquery)?n(m):n.event,p=n.Deferred(),q=n.Callbacks("once memory"),r=l.statusCode||{},s={},t={},u=0,v="canceled",w={readyState:0,getResponseHeader:function(a){var b;if(2===u){if(!k){k={};while(b=Jb.exec(g))k[b[1].toLowerCase()]=b[2]}b=k[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===u?g:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return u||(a=t[c]=t[c]||a,s[a]=b),this},overrideMimeType:function(a){return u||(l.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>u)for(b in a)r[b]=[r[b],a[b]];else w.always(a[w.status]);return this},abort:function(a){var b=a||v;return j&&j.abort(b),y(0,b),this}};if(p.promise(w).complete=q.add,w.success=w.done,w.error=w.fail,l.url=((b||l.url||Rb)+"").replace(Hb,"").replace(Mb,Sb[1]+"//"),l.type=c.method||c.type||l.method||l.type,l.dataTypes=n.trim(l.dataType||"*").toLowerCase().match(G)||[""],null==l.crossDomain&&(d=Nb.exec(l.url.toLowerCase()),l.crossDomain=!(!d||d[1]===Sb[1]&&d[2]===Sb[2]&&(d[3]||("http:"===d[1]?"80":"443"))===(Sb[3]||("http:"===Sb[1]?"80":"443")))),l.data&&l.processData&&"string"!=typeof l.data&&(l.data=n.param(l.data,l.traditional)),Ub(Ob,l,c,w),2===u)return w;i=n.event&&l.global,i&&0===n.active++&&n.event.trigger("ajaxStart"),l.type=l.type.toUpperCase(),l.hasContent=!Lb.test(l.type),f=l.url,l.hasContent||(l.data&&(f=l.url+=(Fb.test(f)?"&":"?")+l.data,delete l.data),l.cache===!1&&(l.url=Ib.test(f)?f.replace(Ib,"$1_="+Eb++):f+(Fb.test(f)?"&":"?")+"_="+Eb++)),l.ifModified&&(n.lastModified[f]&&w.setRequestHeader("If-Modified-Since",n.lastModified[f]),n.etag[f]&&w.setRequestHeader("If-None-Match",n.etag[f])),(l.data&&l.hasContent&&l.contentType!==!1||c.contentType)&&w.setRequestHeader("Content-Type",l.contentType),w.setRequestHeader("Accept",l.dataTypes[0]&&l.accepts[l.dataTypes[0]]?l.accepts[l.dataTypes[0]]+("*"!==l.dataTypes[0]?", "+Qb+"; q=0.01":""):l.accepts["*"]);for(e in l.headers)w.setRequestHeader(e,l.headers[e]);if(l.beforeSend&&(l.beforeSend.call(m,w,l)===!1||2===u))return w.abort();v="abort";for(e in{success:1,error:1,complete:1})w[e](l[e]);if(j=Ub(Pb,l,c,w)){if(w.readyState=1,i&&o.trigger("ajaxSend",[w,l]),2===u)return w;l.async&&l.timeout>0&&(h=a.setTimeout(function(){w.abort("timeout")},l.timeout));try{u=1,j.send(s,y)}catch(x){if(!(2>u))throw x;y(-1,x)}}else y(-1,"No Transport");function y(b,c,d,e){var k,s,t,v,x,y=c;2!==u&&(u=2,h&&a.clearTimeout(h),j=void 0,g=e||"",w.readyState=b>0?4:0,k=b>=200&&300>b||304===b,d&&(v=Wb(l,w,d)),v=Xb(l,v,w,k),k?(l.ifModified&&(x=w.getResponseHeader("Last-Modified"),x&&(n.lastModified[f]=x),x=w.getResponseHeader("etag"),x&&(n.etag[f]=x)),204===b||"HEAD"===l.type?y="nocontent":304===b?y="notmodified":(y=v.state,s=v.data,t=v.error,k=!t)):(t=y,!b&&y||(y="error",0>b&&(b=0))),w.status=b,w.statusText=(c||y)+"",k?p.resolveWith(m,[s,y,w]):p.rejectWith(m,[w,y,t]),w.statusCode(r),r=void 0,i&&o.trigger(k?"ajaxSuccess":"ajaxError",[w,l,k?s:t]),q.fireWith(m,[w,y]),i&&(o.trigger("ajaxComplete",[w,l]),--n.active||n.event.trigger("ajaxStop")))}return w},getJSON:function(a,b,c){return n.get(a,b,c,"json")},getScript:function(a,b){return n.get(a,void 0,b,"script")}}),n.each(["get","post"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax(n.extend({url:a,type:b,dataType:e,data:c,success:d},n.isPlainObject(a)&&a))}}),n._evalUrl=function(a){return n.ajax({url:a,type:"GET",dataType:"script",cache:!0,async:!1,global:!1,"throws":!0})},n.fn.extend({wrapAll:function(a){if(n.isFunction(a))return this.each(function(b){n(this).wrapAll(a.call(this,b))});if(this[0]){var b=n(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return n.isFunction(a)?this.each(function(b){n(this).wrapInner(a.call(this,b))}):this.each(function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,"body")||n(this).replaceWith(this.childNodes)}).end()}});function Yb(a){return a.style&&a.style.display||n.css(a,"display")}function Zb(a){if(!n.contains(a.ownerDocument||d,a))return!0;while(a&&1===a.nodeType){if("none"===Yb(a)||"hidden"===a.type)return!0;a=a.parentNode}return!1}n.expr.filters.hidden=function(a){return l.reliableHiddenOffsets()?a.offsetWidth<=0&&a.offsetHeight<=0&&!a.getClientRects().length:Zb(a)},n.expr.filters.visible=function(a){return!n.expr.filters.hidden(a)};var $b=/%20/g,_b=/\[\]$/,ac=/\r?\n/g,bc=/^(?:submit|button|image|reset|file)$/i,cc=/^(?:input|select|textarea|keygen)/i;function dc(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||_b.test(a)?d(a,e):dc(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)dc(a+"["+e+"]",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)dc(c,a[c],b,e);return d.join("&").replace($b,"+")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,"elements");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(":disabled")&&cc.test(this.nodeName)&&!bc.test(a)&&(this.checked||!Z.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(ac,"\r\n")}}):{name:b.name,value:c.replace(ac,"\r\n")}}).get()}}),n.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return this.isLocal?ic():d.documentMode>8?hc():/^(get|post|head|put|delete|options)$/i.test(this.type)&&hc()||ic()}:hc;var ec=0,fc={},gc=n.ajaxSettings.xhr();a.attachEvent&&a.attachEvent("onunload",function(){for(var a in fc)fc[a](void 0,!0)}),l.cors=!!gc&&"withCredentials"in gc,gc=l.ajax=!!gc,gc&&n.ajaxTransport(function(b){if(!b.crossDomain||l.cors){var c;return{send:function(d,e){var f,g=b.xhr(),h=++ec;if(g.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(f in b.xhrFields)g[f]=b.xhrFields[f];b.mimeType&&g.overrideMimeType&&g.overrideMimeType(b.mimeType),b.crossDomain||d["X-Requested-With"]||(d["X-Requested-With"]="XMLHttpRequest");for(f in d)void 0!==d[f]&&g.setRequestHeader(f,d[f]+"");g.send(b.hasContent&&b.data||null),c=function(a,d){var f,i,j;if(c&&(d||4===g.readyState))if(delete fc[h],c=void 0,g.onreadystatechange=n.noop,d)4!==g.readyState&&g.abort();else{j={},f=g.status,"string"==typeof g.responseText&&(j.text=g.responseText);try{i=g.statusText}catch(k){i=""}f||!b.isLocal||b.crossDomain?1223===f&&(f=204):f=j.text?200:404}j&&e(f,i,j,g.getAllResponseHeaders())},b.async?4===g.readyState?a.setTimeout(c):g.onreadystatechange=fc[h]=c:c()},abort:function(){c&&c(void 0,!0)}}}});function hc(){try{return new a.XMLHttpRequest}catch(b){}}function ic(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}n.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=d.head||n("head")[0]||d.documentElement;return{send:function(e,f){b=d.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||f(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var jc=[],kc=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=jc.pop()||n.expando+"_"+Eb++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(kc.test(b.url)?"url":"string"==typeof b.data&&0===(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&kc.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(kc,"$1"+e):b.jsonp!==!1&&(b.url+=(Fb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||n.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?n(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,jc.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),n.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||d;var e=x.exec(a),f=!c&&[];return e?[b.createElement(e[1])]:(e=ja([a],b,f),f&&f.length&&n(f).remove(),n.merge([],e.childNodes))};var lc=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&lc)return lc.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>-1&&(d=n.trim(a.slice(h,a.length)),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&n.ajax({url:a,type:e||"GET",dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?n("<div>").append(n.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(this,f||[a.responseText,b,a])})}),this},n.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};function mc(a){return n.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,"position"),l=n(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=n.css(a,"top"),i=n.css(a,"left"),j=("absolute"===k||"fixed"===k)&&n.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,n.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,n.contains(b,e)?("undefined"!=typeof e.getBoundingClientRect&&(d=e.getBoundingClientRect()),c=mc(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===n.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(c=a.offset()),c.top+=n.css(a[0],"borderTopWidth",!0),c.left+=n.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-n.css(d,"marginTop",!0),left:b.left-c.left-n.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&!n.nodeName(a,"html")&&"static"===n.css(a,"position"))a=a.offsetParent;return a||Qa})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);n.fn[a]=function(d){return Y(this,function(a,d,e){var f=mc(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?n(f).scrollLeft():e,c?e:n(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=Ua(l.pixelPosition,function(a,c){return c?(c=Sa(a,b),Oa.test(c)?n(a).position()[b]+"px":c):void 0})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({
5padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return Y(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}}),n.fn.size=function(){return this.length},n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var nc=a.jQuery,oc=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=oc),b&&a.jQuery===n&&(a.jQuery=nc),n},b||(a.jQuery=a.$=n),n});
vendor: 1,034 bytes, lines 6-28
6
7;(function(root, factory) {
8  if (typeof define === 'function' && define.amd) {
9    define(['jquery'], factory);
10  } else if (typeof exports === 'object') {
11    module.exports = factory(require('jquery'));
12  } else {
13    root.jquery_mmenu_js = factory(root.jQuery);
14  }
15}(this, function(jQuery) {
16/*
17 * jQuery mmenu v6.1.8
18 * @requires jQuery 1.7.0 or later
19 *
20 * mmenu.frebsite.nl
21 *
22 * Copyright (c) Fred Heusschen
23 * www.frebsite.nl
24 *
25 * License: CC-BY-NC-4.0
26 * http://creativecommons.org/licenses/by-nc/4.0/
27 */
28!function(t){function e(){t[n].glbl||(o={$wndw:t(window),$docu:t(document),$html:t("html"),$body:t("body")},s={},a={},r={},t.each([s,a,r],function(t,e){e.add=function(t){t=t.split(" ");for(var n=0,i=t.length;n<i;n++)e[t[n]]=e.mm(t[n])}}),s.mm=function(t){return"mm-"+t},s.add("wrapper menu panels panel nopanel highest opened subopened navbar hasnavbar title btn prev next listview nolistview inset vertical selected divider spacer hidden fullsubopen noanimation"),s.umm=function(t){return"mm-"==t.slice(0,3)&&(t=t.
28slice(3)),t},a.mm=function(t){return"mm-"+t},a.add("parent child"),r.mm=function(t){return t+".mm"},r.add("transitionend webkitTransitionEnd click scroll resize keydown mousedown mouseup touchstart touchmove touchend orientationchange"),t[n]._c=s,t[n]._d=a,t[n]._e=r,t[n].glbl=o)}var n="mmenu",i="6.1.8";if(!(t[n]&&t[n].version>i)){t[n]=function(t,e,n){return this.$menu=t,this._api=["bind","getInstance","initPanels","openPanel","closePanel","closeAllPanels","setSelected"],this.opts=e,this.conf=n,this.vars={},this.cbck={},this.mtch={},"function"==typeof this.___deprecated&&this.___deprecated(),this._initAddons(),this._initExtensions(),this._initMenu(),this._initPanels(),this._initOpened(),this._initAnchors(),this._initMatchMedia(),"function"==typeof this.___debug&&this.___debug(),this},t[n].version=i,t[n].addons={},t[n].uniqueId=0,t[n].defaults={extensions:[],initMenu:function(){},initPanels:function(){},navbar:{add:!0,title:"Menu",titleLink:"parent"},onClick:{setSelected:!0},slidingSubmenus:!0},t[n].configuration={classNames:{divider:"Divider",inset:"Inset",nolistview:"NoListview",nopanel:"NoPanel",panel:"Panel",selected:"Selected",spacer:"Spacer",vertical:"Vertical"},clone:!1,openingInterval:25,panelNodetype:"ul, ol, div",transitionDuration:400},t[n].prototype={getInstance:function(){return this},initPanels:function(t){this._initPanels(t)},openPanel:function(e,i){if(this.trigger("openPanel:before",e),e&&e.length&&(e.is("."+s.panel)||(e=e.closest("."+s.panel)),e.is("."+s.panel))){var r=this;if("boolean"!=typeof i&&(i=!0),e.hasClass(s.vertical))e.add(e.parents("."+s.vertical)).removeClass(s.hidden).parent("li").addClass(s.opened),this.openPanel(e.parents("."+s.panel).not("."+s.vertical).first()),this.trigger("openPanel:start",e),this.trigger("openPanel:finish",e);else{if(e.hasClass(s.opened))return;var o=this.$pnls.children("."+s.panel),l=o.filter("."+s.opened);if(!t[n].support.csstransitions)return l.addClass(s.hidden).removeClass(s.opened),e.removeClass(s.hidden).addClass(s.opened),this.trigger("openPanel:start",e),void this.trigger("openPanel:finish",e);o.not(e).removeClass(s.subopened);for(var d=e.data(a.parent);d;)d=d.closest("."+s.panel),d.is("."+s.vertical)||d.addClass(s.subopened),d=d.data(a.parent);o.removeClass(s.highest).not(l).not(e).addClass(s.hidden),e.removeClass(s.hidden),this.openPanelStart=function(){l.removeClass(s.opened),e.addClass(s.opened),e.hasClass(s.subopened)?(l.addClass(s.highest),e.removeClass(s.subopened)):(l.addClass(s.subopened),e.addClass(s.highest)),this.trigger("openPanel:start",e)},this.openPanelFinish=function(){l.removeClass(s.highest).addClass(s.hidden),e.removeClass(s.highest),this.trigger("openPanel:finish",e)},i&&!e.hasClass(s.noanimation)?setTimeout(function(){r.__transitionend(e,function(){r.openPanelFinish.call(r)},r.conf.transitionDuration),r.openPanelStart.call(r)},r.conf.openingInterval):(this.openPanelStart.call(this),this.openPanelFinish.call(this))}this.trigger("openPanel:after",e)}},closePanel:function(t){this.trigger("closePanel:before",t);var e=t.parent();e.hasClass(s.vertical)&&(e.removeClass(s.opened),this.trigger("closePanel",t)),this.trigger("closePanel:after",t)},closeAllPanels:function(t){this.trigger("closeAllPanels:before"),this.$pnls.find("."+s.listview).children().removeClass(s.selected).filter("."+s.vertical).removeClass(s.opened);var e=this.$pnls.children("."+s.panel),n=t&&t.length?t:e.first();this.$pnls.children("."+s.panel).not(n).removeClass(s.subopened).removeClass(s.opened).removeClass(s.highest).addClass(s.hidden),this.openPanel(n,!1),this.trigger("closeAllPanels:after")},togglePanel:function(t){var e=t.parent();e.hasClass(s.vertical)&&this[e.hasClass(s.opened)?"closePanel":"openPanel"](t)},setSelected:function(t){this.trigger("setSelected:before",t),this.$menu.find("."+s.listview).children("."+s.selected).removeClass(s.selected),t.addClass(s.selected),this.trigger("setSelected:after",t)},bind:function(t,e){this.cbck[t]=this.cbck[t]||[],this.cbck[t].push(e)},trigger:function(){var t=this,e=Array.prototype.slice.call(arguments),n=e.shift();if(this.cbck[n])for(var i=0,s=this.cbck[n].length;i<s;i++)this.cbck[n][i].apply(t,e)},matchMedia:function(t,e,n){var i={yes:e,no:n};this.mtch[t]=this.mtch[t]||[],this.mtch[t].push(i)},_initAddons:function(){this.trigger("initAddons:before");var e;
28for(e in t[n].addons)t[n].addons[e].add.call(this),t[n].addons[e].add=function(){};for(e in t[n].addons)t[n].addons[e].setup.call(this);this.trigger("initAddons:after")},_initExtensions:function(){this.trigger("initExtensions:before");var t=this;this.opts.extensions.constructor===Array&&(this.opts.extensions={all:this.opts.extensions});for(var e in this.opts.extensions)this.opts.extensions[e]=this.opts.extensions[e].length?"mm-"+this.opts.extensions[e].join(" mm-"):"",this.opts.extensions[e]&&!function(e){t.matchMedia(e,function(){this.$menu.addClass(this.opts.extensions[e])},function(){this.$menu.removeClass(this.opts.extensions[e])})}(e);this.trigger("initExtensions:after")},_initMenu:function(){this.trigger("initMenu:before");this.conf.clone&&(this.$orig=this.$menu,this.$menu=this.$orig.clone(),this.$menu.add(this.$menu.find("[id]")).filter("[id]").each(function(){t(this).attr("id",s.mm(t(this).attr("id")))})),this.opts.initMenu.call(this,this.$menu,this.$orig),this.$menu.attr("id",this.$menu.attr("id")||this.__getUniqueId()),this.$pnls=t('<div class="'+s.panels+'" />').append(this.$menu.children(this.conf.panelNodetype)).prependTo(this.$menu);var e=[s.menu];this.opts.slidingSubmenus||e.push(s.vertical),this.$menu.addClass(e.join(" ")).parent().addClass(s.wrapper),this.trigger("initMenu:after")},_initPanels:function(e){this.trigger("initPanels:before",e),e=e||this.$pnls.children(this.conf.panelNodetype);var n=t(),i=this,a=function(e){e.filter(this.conf.panelNodetype).each(function(){var e=i._initPanel(t(this));if(e){i._initNavbar(e),i._initListview(e),n=n.add(e);var r=e.children("."+s.listview).children("li").children(i.conf.panelNodeType).add(e.children("."+i.conf.classNames.panel));r.length&&a.call(i,r)}})};a.call(this,e),this.opts.initPanels.call(this,n),this.trigger("initPanels:after",n)},_initPanel:function(t){this.trigger("initPanel:before",t);if(t.hasClass(s.panel))return t;if(this.__refactorClass(t,this.conf.classNames.panel,"panel"),this.__refactorClass(t,this.conf.classNames.nopanel,"nopanel"),this.__refactorClass(t,this.conf.classNames.vertical,"vertical"),this.__refactorClass(t,this.conf.classNames.inset,"inset"),t.filter("."+s.inset).addClass(s.nopanel),t.hasClass(s.nopanel))return!1;var e=t.hasClass(s.vertical)||!this.opts.slidingSubmenus;t.removeClass(s.vertical);var n=t.attr("id")||this.__getUniqueId();t.removeAttr("id"),t.is("ul, ol")&&(t.wrap("<div />"),t=t.parent()),t.addClass(s.panel+" "+s.hidden).attr("id",n);var i=t.parent("li");return e?t.add(i).addClass(s.vertical):t.appendTo(this.$pnls),i.length&&(i.data(a.child,t),t.data(a.parent,i)),this.trigger("initPanel:after",t),t},_initNavbar:function(e){if(this.trigger("initNavbar:before",e),!e.children("."+s.navbar).length){var i=e.data(a.parent),r=t('<div class="'+s.navbar+'" />'),o=t[n].i18n(this.opts.navbar.title),l="";if(i&&i.length){if(i.hasClass(s.vertical))return;if(i.parent().is("."+s.listview))var d=i.children("a, span").not("."+s.next);else var d=i.closest("."+s.panel).find('a[href="#'+e.attr("id")+'"]');d=d.first(),i=d.closest("."+s.panel);var c=i.attr("id");switch(o=d.text(),this.opts.navbar.titleLink){case"anchor":l=d.attr("href");break;case"parent":l="#"+c}r.append('<a class="'+s.btn+" "+s.prev+'" href="#'+c+'" />')}else if(!this.opts.navbar.title)return;this.opts.navbar.add&&e.addClass(s.hasnavbar),r.append('<a class="'+s.title+'"'+(l.length?' href="'+l+'"':"")+">"+o+"</a>").prependTo(e),this.trigger("initNavbar:after",e)}},_initListview:function(e){this.trigger("initListview:before",e);var n=this.__childAddBack(e,"ul, ol");this.__refactorClass(n,this.conf.classNames.nolistview,"nolistview"),n.filter("."+this.conf.classNames.inset).addClass(s.nolistview);var i=n.not("."+s.nolistview).addClass(s.listview).children();this.__refactorClass(i,this.conf.classNames.selected,"selected"),this.__refactorClass(i,this.conf.classNames.divider,"divider"),this.__refactorClass(i,this.conf.classNames.spacer,"spacer");var r=e.data(a.parent);if(r&&r.parent().is("."+s.listview)&&!r.children("."+s.next).length){var o=r.children("a, span").first(),l=t('<a class="'+s.next+'" href="#'+e.attr("id")+'" />').insertBefore(o);o.is("span")&&l.addClass(s.fullsubopen)}this.trigger("initListview:after",e)},_initOpened:function(){this.trigger("initOpened:before");var t=this.$pnls.find("."+s.listview).children("."+s.selected).removeClass(s.selected).last(
28).addClass(s.selected),e=t.length?t.closest("."+s.panel):this.$pnls.children("."+s.panel).first();this.openPanel(e,!1),this.trigger("initOpened:after")},_initAnchors:function(){var e=this;o.$body.on(r.click+"-oncanvas","a[href]",function(i){var a=t(this),r=!1,o=e.$menu.find(a).length;for(var l in t[n].addons)if(t[n].addons[l].clickAnchor.call(e,a,o)){r=!0;break}var d=a.attr("href");if(!r&&o&&d.length>1&&"#"==d.slice(0,1))try{var c=t(d,e.$menu);c.is("."+s.panel)&&(r=!0,e[a.parent().hasClass(s.vertical)?"togglePanel":"openPanel"](c))}catch(h){}if(r&&i.preventDefault(),!r&&o&&a.is("."+s.listview+" > li > a")&&!a.is('[rel="external"]')&&!a.is('[target="_blank"]')){e.__valueOrFn(e.opts.onClick.setSelected,a)&&e.setSelected(t(i.target).parent());var f=e.__valueOrFn(e.opts.onClick.preventDefault,a,"#"==d.slice(0,1));f&&i.preventDefault(),e.__valueOrFn(e.opts.onClick.close,a,f)&&e.opts.offCanvas&&"function"==typeof e.close&&e.close()}})},_initMatchMedia:function(){var t=this;this._fireMatchMedia(),o.$wndw.on(r.resize,function(e){t._fireMatchMedia()})},_fireMatchMedia:function(){for(var t in this.mtch)for(var e=window.matchMedia&&window.matchMedia(t).matches?"yes":"no",n=0;n<this.mtch[t].length;n++)this.mtch[t][n][e].call(this)},_getOriginalMenuId:function(){var t=this.$menu.attr("id");return this.conf.clone&&t&&t.length&&(t=s.umm(t)),t},__api:function(){var e=this,n={};return t.each(this._api,function(t){var i=this;n[i]=function(){var t=e[i].apply(e,arguments);return"undefined"==typeof t?n:t}}),n},__valueOrFn:function(t,e,n){return"function"==typeof t?t.call(e[0]):"undefined"==typeof t&&"undefined"!=typeof n?n:t},__refactorClass:function(t,e,n){return t.filter("."+e).removeClass(e).addClass(s[n])},__findAddBack:function(t,e){return t.find(e).add(t.filter(e))},__childAddBack:function(t,e){return t.children(e).add(t.filter(e))},__filterListItems:function(t){return t.not("."+s.divider).not("."+s.hidden)},__filterListItemAnchors:function(t){return this.__filterListItems(t).children("a").not("."+s.next)},__transitionend:function(t,e,n){var i=!1,s=function(n){"undefined"!=typeof n&&n.target!=t[0]||(i||(t.off(r.transitionend),t.off(r.webkitTransitionEnd),e.call(t[0])),i=!0)};t.on(r.transitionend,s),t.on(r.webkitTransitionEnd,s),setTimeout(s,1.1*n)},__getUniqueId:function(){return s.mm(t[n].uniqueId++)}},t.fn[n]=function(i,s){e(),i=t.extend(!0,{},t[n].defaults,i),s=t.extend(!0,{}
28,t[n].configuration,s);var a=t();return this.each(function(){var e=t(this);if(!e.data(n)){var r=new t[n](e,i,s);r.$menu.data(n,r.__api()),a=a.add(r.$menu)}}),a},t[n].i18n=function(){var e={};return function(n){switch(typeof n){case"object":return t.extend(e,n),e;case"string":return e[n]||n;case"undefined":default:return e}}}(),t[n].support={touch:"ontouchstart"in window||navigator.msMaxTouchPoints||!1,csstransitions:function(){return"undefined"==typeof Modernizr||"undefined"==typeof Modernizr.csstransitions||Modernizr.csstransitions}(),csstransforms:function(){return"undefined"==typeof Modernizr||"undefined"==typeof Modernizr.csstransforms||Modernizr.csstransforms}(),csstransforms3d:function(){return"undefined"==typeof Modernizr||"undefined"==typeof Modernizr.csstransforms3d||Modernizr.csstransforms3d}()};var s,a,r,o}}(jQuery),/*
29 * jQuery mmenu offCanvas add-on
30 * mmenu.frebsite.nl
31 *
32 * Copyright (c) Fred Heusschen
33 */
34function(t){var e="mmenu",n="offCanvas";t[e].addons[n]={setup:function(){if(this.opts[n]){var s=this,a=this.opts[n],o=this.conf[n];r=t[e].glbl,this._api=t.merge(this._api,["open","close","setPage"]),"object"!=typeof a&&(a={}),"top"!=a.position&&"bottom"!=a.position||(a.zposition="front"),a=this.opts[n]=t.extend(!0,{},t[e].defaults[n],a),"string"!=typeof o.pageSelector&&(o.pageSelector="> "+o.pageNodetype),this.vars.opened=!1;var l=[i.offcanvas];"left"!=a.position&&l.push(i.mm(a.position)),"back"!=a.zposition&&l.push(i.mm(a.zposition)),t[e].support.csstransforms||l.push(i["no-csstransforms"]),t[e].support.csstransforms3d||l.push(i["no-csstransforms3d"]),this.bind("initMenu:after",function(){var t=this;this.setPage(r.$page),this._initBlocker(),this["_initWindow_"+n](),this.$menu.addClass(l.join(" ")).parent("."+i.wrapper).removeClass(i.wrapper),this.$menu[o.menuInsertMethod](o.menuInsertSelector);var e=window.location.hash;if(e){var s=this._getOriginalMenuId();s&&s==e.slice(1)&&setTimeout(function(){t.open()},1e3)}}),this.bind("initExtensions:after",function(){for(var t=[i.mm("widescreen"),i.mm("iconbar")],e=0;e<t.length;e++)for(var n in this.opts.extensions)if(this.opts.extensions[n].indexOf(t[e])>-1){!function(e,n){s.matchMedia(e,function(){r.$html.addClass(t[n])},function(){r.$html.removeClass(t[n])})}(n,e);break}}),this.bind("open:start:sr-aria",function(){this.__sr_aria(this.$menu,"hidden",!1)}),this.bind("close:finish:sr-aria",function(){this.__sr_aria(this.$menu,"hidden",!0)}),this.bind("initMenu:after:sr-aria",function(){this.__sr_aria(this.$menu,"hidden",!0)})}},add:function(){i=t[e]._c,s=t[e]._d,a=t[e]._e,i.add("offcanvas slideout blocking modal background opening blocker page no-csstransforms3d"),s.add("style")},clickAnchor:function(t,e){var s=this;if(this.opts[n]){var a=this._getOriginalMenuId();if(a&&t.is('[href="#'+a+'"]')){if(e)return!0;var o=t.closest("."+i.menu);if(o.length){var l=o.data("mmenu");if(l&&l.close)return l.close(),s.__transitionend(o,function(){s.open()},s.conf.transitionDuration),!0}return this.open(),!0}if(r.$page)return a=r.$page.first().attr("id"),a&&t.is('[href="#'+a+'"]')?(this.close(),!0):void 0}}},t[e].defaults[n]={position:"left",zposition:"back",blockUI:!0,moveBackground:!0},t[e].configuration[n]={pageNodetype:"div",pageSelector:null,noPageSelector:[],wrapPageIfNeeded:!0,menuInsertMethod:"prependTo",menuInsertSelector:"body"},t[e].prototype.open=function(){if(this.trigger("open:before"),!this.vars.opened){var t=this;this._openSetup(),setTimeout(function(){t._openFinish()},this.conf.openingInterval),this.trigger("open:after")}},t[e].prototype._openSetup=function(){var e=this,o=this.opts[n];this.closeAllOthers(),r.$page.each(function(){t(this).data(s.style,t(this).attr("style")||"")}),r.$wndw.trigger(a.resize+"-"+n,[!0]);var l=[i.opened];o.blockUI&&l.push(i.blocking),"modal"==o.blockUI&&l.push(i.modal),o.moveBackground&&l.push(i.background),"left"!=o.position&&l.push(i.mm(this.opts[n].position)),"back"!=o.zposition&&l.push(i.mm(this.opts[n].zposition)),r.$html.addClass(l.join(" ")),setTimeout(function(){e.vars.opened=!0},this.conf.openingInterval),this.$menu.addClass(i.opened)},t[e].prototype._openFinish=function(){var t=this;this.__transitionend(r.$page.first(),function(){t.trigger("open:finish")},this.conf.transitionDuration),this.trigger("open:start"),r.$html.addClass(i.opening)},t[e].prototype.close=function(){if(this.trigger("close:before"),this.vars.opened){var e=this;this.__transitionend(r.$page.first(),function(){e.$menu.removeClass(i.opened);var a=[i.opened,i.blocking,i.modal,i.background,i.mm(e.opts[n].position),i.mm(e.opts[n].zposition)];r.$html.removeClass(a.join(" ")),r.$page.each(function(){t(this).attr("style",t(this).data(s.style))}),e.vars.opened=!1,e.trigger("close:finish")},this.conf.transitionDuration),this.trigger("close:start"),r.$html.removeClass(i.opening),this.trigger("close:after")}},t[e].prototype.closeAllOthers=function(){r.$body.find("."+i.menu+"."+i.offcanvas).not(this.$menu).each(function(){var n=t(this).data(e);n&&n.close&&n.close()})},t[e].prototype.setPage=function(e){this.trigger("setPage:before",e);var s=this,a=this.conf[n];e&&e.length||(e=r.$body.find(a.pageSelector),a.noPageSelector.length&&(e=e.not(a.noPageSelector.join(", "))),e.length>1&&a.wrapPageIfNeeded&&(e=e.wrapAll("<"+this.conf[n].pageNodetype+" />").parent())),e.each(function(){t(this).attr("id",t(this).attr("id")||s.__getUniqueId())}),e.addClass(i.page+" "+i.slideout),r.$page=e,this.trigger("setPage:after",e)},t[e].prototype["_initWindow_"+n]=function(){r.$wndw.off(a.keydown+"-"+n).on(a.keydown+"-"+n,function(t){if(r.$html.hasClass(i.opened)&&9==t.keyCode)return t.preventDefault(),!1});var t=0;r.$wndw.off(a.resize+"-"+n).on(a.resize+"-"+n,function(e,n){if(1==r.$page.length&&(n||r.$html.hasClass(i.opened))){var s=r.$wndw.height();(n||s!=t)&&(t=s,r.$page.css("minHeight",s))}})},t[e].prototype._initBlocker=function(){var e=this;this.opts[n].blockUI&&(r.$blck||(r.$blck=t('<div id="'+i.blocker+'" class="'+i.slideout+'" />')),r.$blck.appendTo(r.$body).off(a.touchstart+"-"+n+" "+a.touchmove+"-"+n).on(a.touchstart+"-"+n+" "+a.touchmove+"-"+n,function(t){t.preventDefault(),t.stopPropagation(),r.$blck.trigger(a.mousedown+"-"+n)}).off(a.mousedown+"-"+n).on(a.mousedown+"-"+n,function(t){t.preventDefault(),r.$html.hasClass(i.modal)||(e.closeAllOthers(),e.close())}))};var i,s,a,r}(jQuery),/*
35 * jQuery mmenu scrollBugFix add-on
36 * mmenu.frebsite.nl
37 *
38 * Copyright (c) Fred Heusschen
39 */
40function(t){var e="mmenu",n="scrollBugFix";t[e].addons[n]={setup:function(){var s=this.opts[n];this.conf[n];r=t[e].glbl,t[e].support.touch&&this.opts.offCanvas&&this.opts.offCanvas.blockUI&&("boolean"==typeof s&&(s={fix:s}),"object"!=typeof s&&(s={}),s=this.opts[n]=t.extend(!0,{},t[e].defaults[n],s),s.fix&&(this.bind("open:start",function(){this.$pnls.children("."+i.opened).scrollTop(0)}),this.bind("initMenu:after",function(){this["_initWindow_"+n]()})))},add:function(){i=t[e]._c,s=t[e]._d,a=t[e]._e},clickAnchor:function(t,e){}},t[e].defaults[n]={fix:!0},t[e].prototype["_initWindow_"+n]=function(){var e=this;r.$docu.off(a.touchmove+"-"+n).on(a.touchmove+"-"+n,function(t){r.$html.hasClass(i.opened)&&t.preventDefault()});var s=!1;r.$body.off(a.touchstart+"-"+n).on(a.touchstart+"-"+n,"."+i.panels+"> ."+i.panel,function(t){r.$html.hasClass(i.opened)&&(s||(s=!0,0===t.currentTarget.scrollTop?t.currentTarget.scrollTop=1:t.currentTarget.scrollHeight===t.currentTarget.scrollTop+t.currentTarget.offsetHeight&&(t.currentTarget.scrollTop-=1),s=!1))}).off(a.touchmove+"-"+n).on(a.touchmove+"-"+n,"."+i.panels+"> ."+i.panel,function(e){r.$html.hasClass(i.opened)&&t(this)[0].scrollHeight>t(this).innerHeight()&&e.stopPropagation()}),r.$wndw.off(a.orientationchange+"-"+n).on(a.orientationchange+"-"+n,function(){e.$pnls.children("."+i.opened).scrollTop(0).css({"-webkit-overflow-scrolling":"auto"}).css({"-webkit-overflow-scrolling":"touch"})})};var i,s,a,r}(jQuery),/*
41 * jQuery mmenu screenReader add-on
42 * mmenu.frebsite.nl
43 *
44 * Copyright (c) Fred Heusschen
45 */
46function(t){var e="mmenu",n="screenReader";t[e].addons[n]={setup:function(){var a=this,o=this.opts[n],l=this.conf[n];r=t[e].glbl,"boolean"==typeof o&&(o={aria:o,text:o}),"object"!=typeof o&&(o={}),o=this.opts[n]=t.extend(!0,{},t[e].defaults[n],o),o.aria&&(this.bind("initAddons:after",function(){this.bind("initMenu:after",function(){this.trigger("initMenu:after:sr-aria")}),this.bind("initNavbar:after",function(){this.trigger("initNavbar:after:sr-aria",arguments[0])}),this.bind("openPanel:start",function(){this.trigger("openPanel:start:sr-aria",arguments[0])}),this.bind("close:start",function(){this.trigger("close:start:sr-aria")}),this.bind("close:finish",function(){this.trigger("close:finish:sr-aria")}),this.bind("open:start",function(){this.trigger("open:start:sr-aria")}),this.bind("open:finish",function(){this.trigger("open:finish:sr-aria")})}),this.bind("updateListview",function(){this.$pnls.find("."+i.listview).children().each(function(){a.__sr_aria(t(this),"hidden",t(this).is("."+i.hidden))})}),this.bind("openPanel:start",function(t){var e=this.$menu.find("."+i.panel).not(t).not(t.parents("."+i.panel)),n=t.add(t.find("."+i.vertical+"."+i.opened).children("."+i.panel));this.__sr_aria(e,"hidden",!0),this.__sr_aria(n,"hidden",!1)}),this.bind("closePanel",function(t){this.__sr_aria(t,"hidden",!0)}),this.bind("initPanels:after",function(e){var n=e.find("."+i.prev+", ."+i.next).each(function(){a.__sr_aria(t(this),"owns",t(this).attr("href").replace("#",""))});this.__sr_aria(n,"haspopup",!0)}),this.bind("initNavbar:after",function(t){var e=t.children("."+i.navbar);this.__sr_aria(e,"hidden",!t.hasClass(i.hasnavbar))}),o.text&&(this.bind("initlistview:after",function(t){var e=t.find("."+i.listview).find("."+i.fullsubopen).parent().children("span");this.__sr_aria(e,"hidden",!0)}),"parent"==this.opts.navbar.titleLink&&this.bind("initNavbar:after",function(t){var e=t.children("."+i.navbar),n=!!e.children("."+i.prev).length;this.__sr_aria(e.children("."+i.title),"hidden",n)}
46))),o.text&&(this.bind("initAddons:after",function(){this.bind("setPage:after",function(){this.trigger("setPage:after:sr-text",arguments[0])})}),this.bind("initNavbar:after",function(n){var s=n.children("."+i.navbar),a=s.children("."+i.title).text(),r=t[e].i18n(l.text.closeSubmenu);a&&(r+=" ("+a+")"),s.children("."+i.prev).html(this.__sr_text(r))}),this.bind("initListview:after",function(n){var r=n.data(s.parent);if(r&&r.length){var o=r.children("."+i.next),d=o.nextAll("span, a").first().text(),c=t[e].i18n(l.text[o.parent().is("."+i.vertical)?"toggleSubmenu":"openSubmenu"]);d&&(c+=" ("+d+")"),o.html(a.__sr_text(c))}}))},add:function(){i=t[e]._c,s=t[e]._d,a=t[e]._e,i.add("sronly")},clickAnchor:function(t,e){}},t[e].defaults[n]={aria:!0,text:!0},t[e].configuration[n]={text:{closeMenu:"Close menu",closeSubmenu:"Close submenu",openSubmenu:"Open submenu",toggleSubmenu:"Toggle submenu"}},t[e].prototype.__sr_aria=function(t,e,n){t.prop("aria-"+e,n)[n?"attr":"removeAttr"]("aria-"+e,n)},t[e].prototype.__sr_text=function(t){return'<span class="'+i.sronly+'">'+t+"</span>"};var i,s,a,r}(jQuery);
47return true;
48}));
49
50/*
51 * jQuery mmenu navbar add-on
52 * mmenu.frebsite.nl
53 *
54 * Copyright (c) Fred Heusschen
55 */
56!function(a){var n="mmenu",t="navbars";a[n].addons[t]={setup:function(){var r=this,s=this.opts[t],o=this.conf[t];if(i=a[n].glbl,"undefined"!=typeof s){s instanceof Array||(s=[s]);var d={},c={};s.length&&(a.each(s,function(i){var h=s[i];"boolean"==typeof h&&h&&(h={}),"object"!=typeof h&&(h={}),"undefined"==typeof h.content&&(h.content=["prev","title"]),h.content instanceof Array||(h.content=[h.content]),h=a.extend(!0,{},r.opts.navbar,h);var l=a('<div class="'+e.navbar+'" />'),f=h.height;"number"!=typeof f&&(f=1),f=Math.min(4,Math.max(1,f)),l.addClass(e.navbar+"-size-"+f);var v=h.position;"bottom"!=v&&(v="top"),d[v]||(d[v]=0),d[v]+=f,c[v]||(c[v]=a('<div class="'+e.navbars+"-"+v+'" />')),c[v].append(l);for(var b=0,p=0,u=h.content.length;p<u;p++){var m=a[n].addons[t][h.content[p]]||!1;m?b+=m.call(r,l,h,o):(m=h.content[p],m instanceof a||(m=a(h.content[p])),l.append(m))}b+=Math.ceil(l.children().not("."+e.btn).length/f),b>1&&l.addClass(e.navbar+"-content-"+b),l.children("."+e.btn).length&&l.addClass(e.hasbtns)}),this.bind("initMenu:after",function(){for(var a in d)this.$menu.addClass(e.hasnavbar+"-"+a+"-"+d[a]),this.$menu["bottom"==a?"append":"prepend"](c[a])}))}},add:function(){e=a[n]._c,r=a[n]._d,s=a[n]._e,e.add("navbars close hasbtns")},clickAnchor:function(a,n){}},a[n].configuration[t]={breadcrumbSeparator:"/"},a[n].configuration.classNames[t]={};var e,r,s,i}(jQuery),/*
57 * jQuery mmenu navbar add-on breadcrumbs content
58 * mmenu.frebsite.nl
59 *
60 * Copyright (c) Fred Heusschen
61 */
62function(a){var n="mmenu",t="navbars",e="breadcrumbs";a[n].addons[t][e]=function(t,e,r){var s=this,i=a[n]._c,o=a[n]._d;i.add("breadcrumbs separator");var d=a('<span class="'+i.breadcrumbs+'" />').appendTo(t);return this.bind("initNavbar:after",function(n){n.removeClass(i.hasnavbar);for(var t=[],e=a('<span class="'+i.breadcrumbs+'"></span>'),s=n,d=!0;s&&s.length;){if(s.is("."+i.panel)||(s=s.closest("."+i.panel)),!s.hasClass(i.vertical)){var c=s.children("."+i.navbar).children("."+i.title).text();t.unshift(d?"<span>"+c+"</span>":'<a href="#'+s.attr("id")+'">'+c+"</a>"),d=!1}s=s.data(o.parent)}e.append(t.join('<span class="'+i.separator+'">'+r.breadcrumbSeparator+"</span>")).appendTo(n.children("."+i.navbar))}),this.bind("openPanel:start",function(a){d.html(a.children("."+i.navbar).children("."+i.breadcrumbs).html()||"")}),this.bind("initNavbar:after:sr-aria",function(n){n.children("."+i.navbar).children("."+i.breadcrumbs).children("a").each(function(){s.__sr_aria(a(this),"owns",a(this).attr("href").slice(1))})}),0}}(jQuery),/*
63 * jQuery mmenu navbar add-on close content
64 * mmenu.frebsite.nl
65 *
66 * Copyright (c) Fred Heusschen
67 */
68function(a){var n="mmenu",t="navbars",e="close";a[n].addons[t][e]=function(t,e){var r=a[n]._c,s=(a[n].glbl,a('<a class="'+r.close+" "+r.btn+'" href="#" />').appendTo(t));return this.bind("setPage:after",function(a){s.attr("href","#"+a.attr("id"))}),this.bind("setPage:after:sr-text",function(t){s.html(this.__sr_text(a[n].i18n(this.conf.screenReader.text.closeMenu))),this.__sr_aria(s,"owns",s.attr("href").slice(1))}),-1}}(jQuery),/*
69 * jQuery mmenu navbar add-on next content
70 * mmenu.frebsite.nl
71 *
72 * Copyright (c) Fred Heusschen
73 */
74function(a){var n="mmenu",t="navbars",e="next";a[n].addons[t][e]=function(e,r){var s,i,o,d=a[n]._c,c=a('<a class="'+d.next+" "+d.btn+'" href="#" />').appendTo(e);return this.bind("openPanel:start",function(a){s=a.find("."+this.conf.classNames[t].panelNext),i=s.attr("href"),o=s.html(),i?c.attr("href",i):c.removeAttr("href"),c[i||o?"removeClass":"addClass"](d.hidden),c.html(o)}),this.bind("openPanel:start:sr-aria",function(a){this.__sr_aria(c,"hidden",c.hasClass(d.hidden)),this.__sr_aria(c,"owns",(c.attr("href")||"").slice(1))}),-1},a[n].configuration.classNames[t].panelNext="Next"}(jQuery),/*
75 * jQuery mmenu navbar add-on prev content
76 * mmenu.frebsite.nl
77 *
78 * Copyright (c) Fred Heusschen
79 */
80function(a){var n="mmenu",t="navbars",e="prev";a[n].addons[t][e]=function(e,r){var s=a[n]._c,i=a('<a class="'+s.prev+" "+s.btn+'" href="#" />').appendTo(e);this.bind("initNavbar:after",function(a){a.removeClass(s.hasnavbar)});var o,d,c;return this.bind("openPanel:start",function(a){a.hasClass(s.vertical)||(o=a.find("."+this.conf.classNames[t].panelPrev),o.length||(o=a.children("."+s.navbar).children("."+s.prev)),d=o.attr("href"),c=o.html(),d?i.attr("href",d):i.removeAttr("href"),i[d||c?"removeClass":"addClass"](s.hidden),i.html(c))}),this.bind("initNavbar:after:sr-aria",function(a){var n=a.children("."+s.navbar);this.__sr_aria(n,"hidden",!0)}),this.bind("openPanel:start:sr-aria",function(a){this.__sr_aria(i,"hidden",i.hasClass(s.hidden)),this.__sr_aria(i,"owns",(i.attr("href")||"").slice(1))}),-1},a[n].configuration.classNames[t].panelPrev="Prev"}(jQuery),/*
81 * jQuery mmenu navbar add-on searchfield content
82 * mmenu.frebsite.nl
83 *
84 * Copyright (c) Fred Heusschen
85 */
86function(a){var n="mmenu",t="navbars",e="searchfield";a[n].addons[t][e]=function(t,e){var r=a[n]._c,s=a('<div class="'+r.search+'" />').appendTo(t);return"object"!=typeof this.opts.searchfield&&(this.opts.searchfield={}),this.opts.searchfield.add=!0,this.opts.searchfield.addTo=s,0}}(jQuery),/*
87 * jQuery mmenu navbar add-on title content
88 * mmenu.frebsite.nl
89 *
90 * Copyright (c) Fred Heusschen
91 */
92function(a){var n="mmenu",t="navbars",e="title";a[n].addons[t][e]=function(e,r){var s,i,o,d=a[n]._c,c=a('<a class="'+d.title+'" />').appendTo(e);this.bind("openPanel:start",function(a){a.hasClass(d.vertical)||(o=a.find("."+this.conf.classNames[t].panelTitle),o.length||(o=a.children("."+d.navbar).children("."+d.title)),s=o.attr("href"),i=o.html()||r.title,s?c.attr("href",s):c.removeAttr("href"),c[s||i?"removeClass":"addClass"](d.hidden),c.html(i))});var h;
92return this.bind("openPanel:start:sr-aria",function(a){if(this.opts.screenReader.text&&(h||(h=this.$menu.children("."+d.navbars+"-top, ."+d.navbars+"-bottom").children("."+d.navbar).children("."+d.prev)),h.length)){var n=!0;"parent"==this.opts.navbar.titleLink&&(n=!h.hasClass(d.hidden)),this.__sr_aria(c,"hidden",n)}}),0},a[n].configuration.classNames[t].panelTitle="Title"}(jQuery);
93/*! SmartMenus jQuery Plugin - v1.0.1 - November 1, 2016
94 * http://www.smartmenus.org/
95 * Copyright Vasil Dinkov, Vadikom Web Ltd. http://vadikom.com; Licensed MIT */(function(t){"function"==typeof define&&define.amd?define(["jquery"],t):"object"==typeof module&&"object"==typeof module.exports?module.exports=t(require("jquery")):t(jQuery)})(function($){function initMouseDetection(t){var e=".smartmenus_mouse";if(mouseDetectionEnabled||t)mouseDetectionEnabled&&t&&($(document).unbind(e),mouseDetectionEnabled=!1);else{var i=!0,s=null;$(document).bind(getEventsNS([["mousemove",function(t){var e={x:t.pageX,y:t.pageY,timeStamp:(new Date).getTime()};if(s){var o=Math.abs(s.x-e.x),a=Math.abs(s.y-e.y);if((o>0||a>0)&&2>=o&&2>=a&&300>=e.timeStamp-s.timeStamp&&(mouse=!0,i)){var n=$(t.target).closest("a");n.is("a")&&$.each(menuTrees,function(){return $.contains(this.$root[0],n[0])?(this.itemEnter({currentTarget:n[0]}),!1):void 0}),i=!1}}s=e}],[touchEvents?"touchstart":"pointerover pointermove pointerout MSPointerOver MSPointerMove MSPointerOut",function(t){isTouchEvent(t.originalEvent)&&(mouse=!1)}]],e)),mouseDetectionEnabled=!0}}function isTouchEvent(t){return!/^(4|mouse)$/.test(t.pointerType)}function getEventsNS(t,e){e||(e="");var i={};return $.each(t,function(t,s){i[s[0].split(" ").join(e+" ")+e]=s[1]}),i}var menuTrees=[],IE=!!window.createPopup,mouse=!1,touchEvents="ontouchstart"in window,mouseDetectionEnabled=!1,requestAnimationFrame=window.requestAnimationFrame||function(t){return setTimeout(t,1e3/60)},cancelAnimationFrame=window.cancelAnimationFrame||function(t){clearTimeout(t)};return $.SmartMenus=function(t,e){this.$root=$(t),this.opts=e,this.rootId="",this.accessIdPrefix="",this.$subArrow=null,this.activatedItems=[],this.visibleSubMenus=[],this.showTimeout=0,this.hideTimeout=0,this.scrollTimeout=0,this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.idInc=0,this.$firstLink=null,this.$firstSub=null,this.disabled=!1,this.$disableOverlay=null,this.$touchScrollingSub=null,this.cssTransforms3d="perspective"in t.style||"webkitPerspective"in t.style,this.wasCollapsible=!1,this.init()},$.extend($.SmartMenus,{hideAll:function(){$.each(menuTrees,function(){this.menuHideAll()})},destroy:function(){for(;menuTrees.length;)menuTrees[0].destroy();initMouseDetection(!0)},prototype:{init:function(t){var e=this;if(!t){menuTrees.push(this),this.rootId=((new Date).getTime()+Math.random()+"").replace(/\D/g,""),this.accessIdPrefix="sm-"+this.rootId+"-",this.$root.hasClass("sm-rtl")&&(this.opts.rightToLeftSubMenus=!0);var i=".smartmenus";this.$root.data("smartmenus",this).attr("data-smartmenus-id",this.rootId).dataSM("level",1).bind(getEventsNS([["mouseover focusin",$.proxy(this.rootOver,this)],["mouseout focusout",$.proxy(this.rootOut,this)],["keydown",$.proxy(this.rootKeyDown,this)]],i)).delegate("a",getEventsNS([["mouseenter",$.proxy(this.itemEnter,this)],["mouseleave",$.proxy(this.itemLeave,this)],["mousedown",$.proxy(this.itemDown,this)],["focus",$.proxy(this.itemFocus,this)],["blur",$.proxy(this.itemBlur,this)],["click",$.proxy(this.itemClick,this)]],i)),i+=this.rootId,this.opts.hideOnClick&&$(document).bind(getEventsNS([["touchstart",$.proxy(this.docTouchStart,this)],["touchmove",$.proxy(this.docTouchMove,this)],["touchend",$.proxy(this.docTouchEnd,this)],["click",$.proxy(this.docClick,this)]],i)),$(window).bind(getEventsNS([["resize orientationchange",$.proxy(this.winResize,this)]],i)),this.opts.subIndicators&&(this.$subArrow=$("<span/>").addClass("sub-arrow"),this.opts.subIndicatorsText&&this.$subArrow.html(this.opts.subIndicatorsText)),initMouseDetection()}if(this.$firstSub=this.$root.find("ul").each(function(){e.menuInit($(this))}).eq(0),this.$firstLink=this.$root.find("a").eq(0),this.opts.markCurrentItem){var s=/(index|default)\.[^#\?\/]*/i,o=/#.*/,a=window.location.href.replace(s,""),n=a.replace(o,"");this.$root.find("a").each(function(){var t=this.href.replace(s,""),i=$(this);(t==a||t==n)&&(i.addClass("current"),e.opts.markCurrentTree&&i.parentsUntil("[data-smartmenus-id]","ul").each(function(){$(this).dataSM("parent-a").addClass("current")}))})}this.wasCollapsible=this.isCollapsible()},destroy:function(t){if(!t){var e=".smartmenus";this.$root.removeData("smartmenus").removeAttr("data-smartmenus-id").removeDataSM("level").unbind(e).undelegate(e),e+=this.rootId,$(document).unbind(e),$(window).unbind(e),this.opts.subIndicators&&(this.$subArrow=null)}this.menuHideAll();var i=this;this.$root.find("ul").each(function(){var t=$(this);t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.dataSM("shown-before")&&((i.opts.subMenusMinWidth||i.opts.subMenusMaxWidth)&&t.css({width:"",minWidth:"",maxWidth:""}).removeClass("sm-nowrap"),t.dataSM("scroll-arrows")&&t.dataSM("scroll-arrows").remove(),t.css({zIndex:"",top:"",left:"",marginLeft:"",marginTop:"",display:""})),0==(t.attr("id")||"").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeDataSM("in-mega").removeDataSM("shown-before").removeDataSM("ie-shim").removeDataSM("scroll-arrows").removeDataSM("parent-a").removeDataSM("level").removeDataSM("beforefirstshowfired").removeAttr("role").removeAttr("aria-hidden").removeAttr("aria-labelledby").removeAttr("aria-expanded"),this.$root.find("a.has-submenu").each(function(){var t=$(this);0==t.attr("id").indexOf(i.accessIdPrefix)&&t.removeAttr("id")}).removeClass("has-submenu").removeDataSM("sub").removeAttr("aria-haspopup").removeAttr("aria-controls").removeAttr("aria-expanded").closest("li").removeDataSM("sub"),this.opts.subIndicators&&this.$root.find("span.sub-arrow").remove(),this.opts.markCurrentItem&&this.$root.find("a.current").removeClass("current"),t||(this.$root=null,this.$firstLink=null,this.$firstSub=null,this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),menuTrees.splice($.inArray(this,menuTrees),1))},disable:function(t){if(!this.disabled){if(this.menuHideAll(),!t&&!this.opts.isPopup&&this.$root.is(":visible")){var e=this.$root.offset();this.$disableOverlay=$('<div class="sm-jquery-disable-overlay"/>
95').css({position:"absolute",top:e.top,left:e.left,width:this.$root.outerWidth(),height:this.$root.outerHeight(),zIndex:this.getStartZIndex(!0),opacity:0}).appendTo(document.body)}this.disabled=!0}},docClick:function(t){return this.$touchScrollingSub?(this.$touchScrollingSub=null,void 0):((this.visibleSubMenus.length&&!$.contains(this.$root[0],t.target)||$(t.target).is("a"))&&this.menuHideAll(),void 0)},docTouchEnd:function(){if(this.lastTouch){if(!(!this.visibleSubMenus.length||void 0!==this.lastTouch.x2&&this.lastTouch.x1!=this.lastTouch.x2||void 0!==this.lastTouch.y2&&this.lastTouch.y1!=this.lastTouch.y2||this.lastTouch.target&&$.contains(this.$root[0],this.lastTouch.target))){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var t=this;this.hideTimeout=setTimeout(function(){t.menuHideAll()},350)}this.lastTouch=null}},docTouchMove:function(t){if(this.lastTouch){var e=t.originalEvent.touches[0];this.lastTouch.x2=e.pageX,this.lastTouch.y2=e.pageY}},docTouchStart:function(t){var e=t.originalEvent.touches[0];this.lastTouch={x1:e.pageX,y1:e.pageY,target:e.target}},enable:function(){this.disabled&&(this.$disableOverlay&&(this.$disableOverlay.remove(),this.$disableOverlay=null),this.disabled=!1)},getClosestMenu:function(t){for(var e=$(t).closest("ul");e.dataSM("in-mega");)e=e.parent().closest("ul");return e[0]||null},getHeight:function(t){return this.getOffset(t,!0)},getOffset:function(t,e){var i;"none"==t.css("display")&&(i={position:t[0].style.position,visibility:t[0].style.visibility},t.css({position:"absolute",visibility:"hidden"}).show());var s=t[0].getBoundingClientRect&&t[0].getBoundingClientRect(),o=s&&(e?s.height||s.bottom-s.top:s.width||s.right-s.left);return o||0===o||(o=e?t[0].offsetHeight:t[0].offsetWidth),i&&t.hide().css(i),o},getStartZIndex:function(t){var e=parseInt(this[t?"$root":"$firstSub"].css("z-index"));return!t&&isNaN(e)&&(e=parseInt(this.$root.css("z-index"))),isNaN(e)?1:e},getTouchPoint:function(t){return t.touches&&t.touches[0]||t.changedTouches&&t.changedTouches[0]||t},getViewport:function(t){var e=t?"Height":"Width",i=document.documentElement["client"+e],s=window["inner"+e];return s&&(i=Math.min(i,s)),i},getViewportHeight:function(){return this.getViewport(!0)},getViewportWidth:function(){return this.getViewport()},getWidth:function(t){return this.getOffset(t)},handleEvents:function(){return!this.disabled&&this.isCSSOn()},handleItemEvents:function(t){return this.handleEvents()&&!this.isLinkInMegaMenu(t)},isCollapsible:function(){return"static"==this.$firstSub.css("position")},isCSSOn:function(){return"block"==this.$firstLink.css("display")},isFixed:function(){var t="fixed"==this.$root.css("position");return t||this.$root.parentsUntil("body").each(function(){return"fixed"==$(this).css("position")?(t=!0,!1):void 0}),t},isLinkInMegaMenu:function(t){return $(this.getClosestMenu(t[0])).hasClass("mega-menu")},isTouchMode:function(){return!mouse||this.opts.noMouseOver||this.isCollapsible()},itemActivate:function(t,e){var i=t.closest("ul"),s=i.dataSM("level");if(s>1&&(!this.activatedItems[s-2]||this.activatedItems[s-2][0]!=i.dataSM("parent-a")[0])){var o=this;$(i.parentsUntil("[data-smartmenus-id]","ul").get().reverse()).add(i).each(function(){o.itemActivate($(this).dataSM("parent-a"))})}if((!this.isCollapsible()||e)&&this.menuHideSubMenus(this.activatedItems[s-1]&&this.activatedItems[s-1][0]==t[0]?s:s-1),this.activatedItems[s-1]=t,this.$root.triggerHandler("activate.smapi",t[0])!==!1){var a=t.dataSM("sub");a&&(this.isTouchMode()||!this.opts.showOnClick||this.clickActivated)&&this.menuShow(a)}},itemBlur:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&this.$root.triggerHandler("blur.smapi",e[0])},itemClick:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(this.$touchScrollingSub&&this.$touchScrollingSub[0]==e.closest("ul")[0])return this.$touchScrollingSub=null,t.stopPropagation(),!1;if(this.$root.triggerHandler("click.smapi",e[0])===!1)return!1;var i=$(t.target).is("span.sub-arrow"),s=e.dataSM("sub"),o=s?2==s.dataSM("level"):!1;if(s&&!s.is(":visible")){if(this.opts.showOnClick&&o&&(this.clickActivated=!0),this.itemActivate(e),s.is(":visible"))return this.focusActivated=!0,!1}else if(this.isCollapsible()&&i)return this.itemActivate(e),this.menuHide(s),!1;return this.opts.showOnClick&&o||e.hasClass("disabled")||this.$root.triggerHandler("select.smapi",e[0])===!1?!1:void 0}}
95,itemDown:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&e.dataSM("mousedown",!0)},itemEnter:function(t){var e=$(t.currentTarget);if(this.handleItemEvents(e)){if(!this.isTouchMode()){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);var i=this;this.showTimeout=setTimeout(function(){i.itemActivate(e)},this.opts.showOnClick&&1==e.closest("ul").dataSM("level")?1:this.opts.showTimeout)}this.$root.triggerHandler("mouseenter.smapi",e[0])}},itemFocus:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(!this.focusActivated||this.isTouchMode()&&e.dataSM("mousedown")||this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0]==e[0]||this.itemActivate(e,!0),this.$root.triggerHandler("focus.smapi",e[0]))},itemLeave:function(t){var e=$(t.currentTarget);this.handleItemEvents(e)&&(this.isTouchMode()||(e[0].blur(),this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0)),e.removeDataSM("mousedown"),this.$root.triggerHandler("mouseleave.smapi",e[0]))},menuHide:function(t){if(this.$root.triggerHandler("beforehide.smapi",t[0])!==!1&&(t.stop(!0,!0),"none"!=t.css("display"))){var e=function(){t.css("z-index","")};this.isCollapsible()?this.opts.collapsibleHideFunction?this.opts.collapsibleHideFunction.call(this,t,e):t.hide(this.opts.collapsibleHideDuration,e):this.opts.hideFunction?this.opts.hideFunction.call(this,t,e):t.hide(this.opts.hideDuration,e),t.dataSM("ie-shim")&&t.dataSM("ie-shim").remove().css({"-webkit-transform":"",transform:""}),t.dataSM("scroll")&&(this.menuScrollStop(t),t.css({"touch-action":"","-ms-touch-action":"","-webkit-transform":"",transform:""}).unbind(".smartmenus_scroll").removeDataSM("scroll").dataSM("scroll-arrows").hide()),t.dataSM("parent-a").removeClass("highlighted").attr("aria-expanded","false"),t.attr({"aria-expanded":"false","aria-hidden":"true"});var i=t.dataSM("level");this.activatedItems.splice(i-1,1),this.visibleSubMenus.splice($.inArray(t,this.visibleSubMenus),1),this.$root.triggerHandler("hide.smapi",t[0])}},menuHideAll:function(){this.showTimeout&&(clearTimeout(this.showTimeout),this.showTimeout=0);for(var t=this.opts.isPopup?1:0,e=this.visibleSubMenus.length-1;e>=t;e--)this.menuHide(this.visibleSubMenus[e]);this.opts.isPopup&&(this.$root.stop(!0,!0),this.$root.is(":visible")&&(this.opts.hideFunction?this.opts.hideFunction.call(this,this.$root):this.$root.hide(this.opts.hideDuration),this.$root.dataSM("ie-shim")&&this.$root.dataSM("ie-shim").remove())),this.activatedItems=[],this.visibleSubMenus=[],this.clickActivated=!1,this.focusActivated=!1,this.zIndexInc=0,this.$root.triggerHandler("hideAll.smapi")},menuHideSubMenus:function(t){for(var e=this.activatedItems.length-1;e>=t;e--){var i=this.activatedItems[e].dataSM("sub");i&&this.menuHide(i)}},menuIframeShim:function(t){IE&&this.opts.overlapControlsInIE&&!t.dataSM("ie-shim")&&t.dataSM("ie-shim",$("<iframe/>").attr({src:"javascript:0",tabindex:-9}).css({position:"absolute",top:"auto",left:"0",opacity:0,border:"0"}))},menuInit:function(t){if(!t.dataSM("in-mega")){t.hasClass("mega-menu")&&t.find("ul").dataSM("in-mega",!0);for(var e=2,i=t[0];(i=i.parentNode.parentNode)!=this.$root[0];)e++;var s=t.prevAll("a").eq(-1);s.length||(s=t.prevAll().find("a").eq(-1)),s.addClass("has-submenu").dataSM("sub",t),t.dataSM("parent-a",s).dataSM("level",e).parent().dataSM("sub",t);var o=s.attr("id")||this.accessIdPrefix+ ++this.idInc,a=t.attr("id")||this.accessIdPrefix+ ++this.idInc;s.attr({id:o,"aria-haspopup":"true","aria-controls":a,"aria-expanded":"false"}),t.attr({id:a,role:"group","aria-hidden":"true","aria-labelledby":o,"aria-expanded":"false"}),this.opts.subIndicators&&s[this.opts.subIndicatorsPos](this.$subArrow.clone())}},menuPosition:function(t){var e,i,s=t.dataSM("parent-a"),o=s.closest("li"),a=o.parent(),n=t.dataSM("level"),r=this.getWidth(t),h=this.getHeight(t),u=s.offset(),l=u.left,c=u.top,d=this.getWidth(s),m=this.getHeight(s),p=$(window),f=p.scrollLeft(),v=p.scrollTop(),S=this.getViewportWidth(),b=this.getViewportHeight(),g=a.parent().is("[data-sm-horizontal-sub]")||2==n&&!a.hasClass("sm-vertical"),M=this.opts.rightToLeftSubMenus&&!o.is("[data-sm-reverse]")||!this.opts.rightToLeftSubMenus&&o.is("[data-sm-reverse]"),w=2==n?this.opts.mainMenu
95SubOffsetX:this.opts.subMenusSubOffsetX,T=2==n?this.opts.mainMenuSubOffsetY:this.opts.subMenusSubOffsetY;if(g?(e=M?d-r-w:w,i=this.opts.bottomToTopSubMenus?-h-T:m+T):(e=M?w-r:d-w,i=this.opts.bottomToTopSubMenus?m-T-h:T),this.opts.keepInViewport){var y=l+e,I=c+i;if(M&&f>y?e=g?f-y+e:d-w:!M&&y+r>f+S&&(e=g?f+S-r-y+e:w-r),g||(b>h&&I+h>v+b?i+=v+b-h-I:(h>=b||v>I)&&(i+=v-I)),g&&(I+h>v+b+.49||v>I)||!g&&h>b+.49){var x=this;t.dataSM("scroll-arrows")||t.dataSM("scroll-arrows",$([$('<span class="scroll-up"><span class="scroll-up-arrow"></span></span>')[0],$('<span class="scroll-down"><span class="scroll-down-arrow"></span></span>')[0]]).bind({mouseenter:function(){t.dataSM("scroll").up=$(this).hasClass("scroll-up"),x.menuScroll(t)},mouseleave:function(e){x.menuScrollStop(t),x.menuScrollOut(t,e)},"mousewheel DOMMouseScroll":function(t){t.preventDefault()}}).insertAfter(t));var C=".smartmenus_scroll";t.dataSM("scroll",{y:this.cssTransforms3d?0:i-m,step:1,itemH:m,subH:h,arrowDownH:this.getHeight(t.dataSM("scroll-arrows").eq(1))}).bind(getEventsNS([["mouseover",function(e){x.menuScrollOver(t,e)}],["mouseout",function(e){x.menuScrollOut(t,e)}],["mousewheel DOMMouseScroll",function(e){x.menuScrollMousewheel(t,e)}]],C)).dataSM("scroll-arrows").css({top:"auto",left:"0",marginLeft:e+(parseInt(t.css("border-left-width"))||0),width:r-(parseInt(t.css("border-left-width"))||0)-(parseInt(t.css("border-right-width"))||0),zIndex:t.css("z-index")}).eq(g&&this.opts.bottomToTopSubMenus?0:1).show(),this.isFixed()&&t.css({"touch-action":"none","-ms-touch-action":"none"}).bind(getEventsNS([[touchEvents?"touchstart touchmove touchend":"pointerdown pointermove pointerup MSPointerDown MSPointerMove MSPointerUp",function(e){x.menuScrollTouch(t,e)}]],C))}}t.css({top:"auto",left:"0",marginLeft:e,marginTop:i-m}),this.menuIframeShim(t),t.dataSM("ie-shim")&&t.dataSM("ie-shim").css({zIndex:t.css("z-index"),width:r,height:h,marginLeft:e,marginTop:i-m})},menuScroll:function(t,e,i){var s,o=t.dataSM("scroll"),a=t.dataSM("scroll-arrows"),n=o.up?o.upEnd:o.downEnd;if(!e&&o.momentum){if(o.momentum*=.92,s=o.momentum,.5>s)return this.menuScrollStop(t),void 0}else s=i||(e||!this.opts.scrollAccelerate?this.opts.scrollStep:Math.floor(o.step));var r=t.dataSM("level");if(this.activatedItems[r-1]&&this.activatedItems[r-1].dataSM("sub")&&this.activatedItems[r-1].dataSM("sub").is(":visible")&&this.menuHideSubMenus(r-1),o.y=o.up&&o.y>=n||!o.up&&n>=o.y?o.y:Math.abs(n-o.y)>s?o.y+(o.up?s:-s):n,t.add(t.dataSM("ie-shim")).css(this.cssTransforms3d?{"-webkit-transform":"translate3d(0, "+o.y+"px, 0)",transform:"translate3d(0, "+o.y+"px, 0)"}:{marginTop:o.y}),mouse&&(o.up&&o.y>o.downEnd||!o.up&&o.y<o.upEnd)&&a.eq(o.up?1:0).show(),o.y==n)mouse&&a.eq(o.up?0:1).hide(),this.menuScrollStop(t);else if(!e){this.opts.scrollAccelerate&&o.step<this.opts.scrollStep&&(o.step+=.2);var h=this;this.scrollTimeout=requestAnimationFrame(function(){h.menuScroll(t)})}},menuScrollMousewheel:function(t,e){if(this.getClosestMenu(e.target)==t[0]){e=e.originalEvent;var i=(e.wheelDelta||-e.detail)>0;t.dataSM("scroll-arrows").eq(i?0:1).is(":visible")&&(t.dataSM("scroll").up=i,this.menuScroll(t,!0))}e.preventDefault()},menuScrollOut:function(t,e){mouse&&(/^scroll-(up|down)/.test((e.relatedTarget||"").className)||(t[0]==e.relatedTarget||$.contains(t[0],e.relatedTarget))&&this.getClosestMenu(e.relatedTarget)==t[0]||t.dataSM("scroll-arrows").css("visibility","hidden"))},menuScrollOver:function(t,e){if(mouse&&!/^scroll-(up|down)/.test(e.target.className)&&this.getClosestMenu(e.target)==t[0]){this.menuScrollRefreshData(t);var i=t.dataSM("scroll"),s=$(window).scrollTop()-t.dataSM("parent-a").offset().top-i.itemH;t.dataSM("scroll-arrows").eq(0).css("margin-top",s).end().eq(1).css("margin-top",s+this.getViewportHeight()-i.arrowDownH).end().css("visibility","visible")}},menuScrollRefreshData:function(t){var e=t.dataSM("scroll"),i=$(window).scrollTop()-t.dataSM("parent-a").offset().top-e.itemH;this.cssTransforms3d&&(i=-(parseFloat(t.css("margin-top"))-i)),$.extend(e,{upEnd:i,downEnd:i+this.getViewportHeight()-e.subH})},menuScrollStop:function(t){return this.scrollTimeout?(cancelAnimationFrame(this.scrollTimeout),this.scrollTimeout=0,t.dataSM("scroll").step=1,!0):void 0},menuScrollTouch:function(t,e){if(e=e.originalEvent,isTouchEvent(e)){var i=this.getTouchPoint(e);if(this.getClosestMenu(i.target)==t[0]){var s=t.dataSM("scroll");
95if(/(start|down)$/i.test(e.type))this.menuScrollStop(t)?(e.preventDefault(),this.$touchScrollingSub=t):this.$touchScrollingSub=null,this.menuScrollRefreshData(t),$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp});else if(/move$/i.test(e.type)){var o=void 0!==s.touchY?s.touchY:s.touchStartY;if(void 0!==o&&o!=i.pageY){this.$touchScrollingSub=t;var a=i.pageY>o;void 0!==s.up&&s.up!=a&&$.extend(s,{touchStartY:i.pageY,touchStartTime:e.timeStamp}),$.extend(s,{up:a,touchY:i.pageY}),this.menuScroll(t,!0,Math.abs(i.pageY-o))}e.preventDefault()}else void 0!==s.touchY&&((s.momentum=15*Math.pow(Math.abs(i.pageY-s.touchStartY)/(e.timeStamp-s.touchStartTime),2))&&(this.menuScrollStop(t),this.menuScroll(t),e.preventDefault()),delete s.touchY)}}},menuShow:function(t){if((t.dataSM("beforefirstshowfired")||(t.dataSM("beforefirstshowfired",!0),this.$root.triggerHandler("beforefirstshow.smapi",t[0])!==!1))&&this.$root.triggerHandler("beforeshow.smapi",t[0])!==!1&&(t.dataSM("shown-before",!0).stop(!0,!0),!t.is(":visible"))){var e=t.dataSM("parent-a");if((this.opts.keepHighlighted||this.isCollapsible())&&e.addClass("highlighted"),this.isCollapsible())t.removeClass("sm-nowrap").css({zIndex:"",width:"auto",minWidth:"",maxWidth:"",top:"",left:"",marginLeft:"",marginTop:""});else{if(t.css("z-index",this.zIndexInc=(this.zIndexInc||this.getStartZIndex())+1),(this.opts.subMenusMinWidth||this.opts.subMenusMaxWidth)&&(t.css({width:"auto",minWidth:"",maxWidth:""}).addClass("sm-nowrap"),this.opts.subMenusMinWidth&&t.css("min-width",this.opts.subMenusMinWidth),this.opts.subMenusMaxWidth)){var i=this.getWidth(t);t.css("max-width",this.opts.subMenusMaxWidth),i>this.getWidth(t)&&t.removeClass("sm-nowrap").css("width",this.opts.subMenusMaxWidth)}this.menuPosition(t),t.dataSM("ie-shim")&&t.dataSM("ie-shim").insertBefore(t)}var s=function(){t.css("overflow","")};this.isCollapsible()?this.opts.collapsibleShowFunction?this.opts.collapsibleShowFunction.call(this,t,s):t.show(this.opts.collapsibleShowDuration,s):this.opts.showFunction?this.opts.showFunction.call(this,t,s):t.show(this.opts.showDuration,s),e.attr("aria-expanded","true"),t.attr({"aria-expanded":"true","aria-hidden":"false"}),this.visibleSubMenus.push(t),this.$root.triggerHandler("show.smapi",t[0])}},popupHide:function(t){this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0);var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},t?1:this.opts.hideTimeout)},popupShow:function(t,e){if(!this.opts.isPopup)return alert('SmartMenus jQuery Error:\n\nIf you want to show this menu via the "popupShow" method, set the isPopup:true option.'),void 0;if(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),this.$root.dataSM("shown-before",!0).stop(!0,!0),!this.$root.is(":visible")){this.$root.css({left:t,top:e}),this.menuIframeShim(this.$root),this.$root.dataSM("ie-shim")&&this.$root.dataSM("ie-shim").css({zIndex:this.$root.css("z-index"),width:this.getWidth(this.$root),height:this.getHeight(this.$root),left:t,top:e}).insertBefore(this.$root);var i=this,s=function(){i.$root.css("overflow","")};this.opts.showFunction?this.opts.showFunction.call(this,this.$root,s):this.$root.show(this.opts.showDuration,s),this.visibleSubMenus[0]=this.$root}},refresh:function(){this.destroy(!0),this.init(!0)},rootKeyDown:function(t){if(this.handleEvents())switch(t.keyCode){case 27:var e=this.activatedItems[0];if(e){this.menuHideAll(),e[0].focus();var i=e.dataSM("sub");i&&this.menuHide(i)}break;case 32:var s=$(t.target);if(s.is("a")&&this.handleItemEvents(s)){var i=s.dataSM("sub");i&&!i.is(":visible")&&(this.itemClick({currentTarget:t.target}),t.preventDefault())}}},rootOut:function(t){if(this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&(this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0),!this.opts.showOnClick||!this.opts.hideOnClick)){var e=this;this.hideTimeout=setTimeout(function(){e.menuHideAll()},this.opts.hideTimeout)}},rootOver:function(t){this.handleEvents()&&!this.isTouchMode()&&t.target!=this.$root[0]&&this.hideTimeout&&(clearTimeout(this.hideTimeout),this.hideTimeout=0)},winResize:function(t){if(this.handleEvents()){if(!("onorientationchange"in window)||"orientationchange"==t.type){var e=this.isCollapsible();this.wasCollapsible&&e||(this.activatedItems.length&&this.activatedItems[this.activatedItems.length-1][0].blur(),this.menuHideAll()),this.wasCollapsible=e}}else if(this.$disableOverlay){var i=this.$root.offset();
95this.$disableOverlay.css({top:i.top,left:i.left,width:this.$root.outerWidth(),height:this.$root.outerHeight()})}}}}),$.fn.dataSM=function(t,e){return e?this.data(t+"_smartmenus",e):this.data(t+"_smartmenus")},$.fn.removeDataSM=function(t){return this.removeData(t+"_smartmenus")},$.fn.smartmenus=function(options){if("string"==typeof options){var args=arguments,method=options;return Array.prototype.shift.call(args),this.each(function(){var t=$(this).data("smartmenus");t&&t[method]&&t[method].apply(t,args)})}var dataOpts=this.data("sm-options")||null;if(dataOpts)try{dataOpts=eval("("+dataOpts+")")}catch(e){dataOpts=null,alert('ERROR\n\nSmartMenus jQuery init:\nInvalid "data-sm-options" attribute value syntax.')}return this.each(function(){new $.SmartMenus(this,$.extend({},$.fn.smartmenus.defaults,options,dataOpts))})},$.fn.smartmenus.defaults={isPopup:!1,mainMenuSubOffsetX:0,mainMenuSubOffsetY:0,subMenusSubOffsetX:0,subMenusSubOffsetY:0,subMenusMinWidth:"10em",subMenusMaxWidth:"20em",subIndicators:!0,subIndicatorsPos:"prepend",subIndicatorsText:"+",scrollStep:30,scrollAccelerate:!0,showTimeout:250,hideTimeout:500,showDuration:0,showFunction:null,hideDuration:0,hideFunction:function(t,e){t.fadeOut(200,e)},collapsibleShowDuration:0,collapsibleShowFunction:function(t,e){t.slideDown(200,e)},collapsibleHideDuration:0,collapsibleHideFunction:function(t,e){t.slideUp(200,e)},showOnClick:!1,hideOnClick:!0,noMouseOver:!1,keepInViewport:!0,keepHighlighted:!0,markCurrentItem:!1,markCurrentTree:!0,rightToLeftSubMenus:!1,bottomToTopSubMenus:!1,overlapControlsInIE:!0},$});
96// SmartMenus init
97$(function() {
98  $('#main-menu').smartmenus({
99    mainMenuSubOffsetX: -1,
100    mainMenuSubOffsetY: 4,
101    subMenusSubOffsetX: 6,
102    subMenusSubOffsetY: -6,
103    subMenusMinWidth: '14em'
104  });
105});
106/* @preserve
107 * Leaflet 1.3.4+Detached: 0e566b2ad5e696ba9f79a9d48a7e51c8f4892441.0e566b2, a JS library for interactive maps. http://leafletjs.com
108 * (c) 2010-2018 Vladimir Agafonkin, (c) 2010-2011 CloudMade
109 */
110
111(function (global, factory) {
112	typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
113	typeof define === 'function' && define.amd ? define(['exports'], factory) :
114	(factory((global.L = {})));
115}(this, (function (exports) { 'use strict';
116
117var version = "1.3.4+HEAD.0e566b2";
118
119/*
120 * @namespace Util
121 *
122 * Various utility functions, used by Leaflet internally.
123 */
124
125var freeze = Object.freeze;
126Object.freeze = function (obj) { return obj; };
127
128// @function extend(dest: Object, src?: Object): Object
129// Merges the properties of the `src` object (or multiple objects) into `dest` object and returns the latter. Has an `L.extend` shortcut.
130function extend(dest) {
131	var i, j, len, src;
132
133	for (j = 1, len = arguments.length; j < len; j++) {
134		src = arguments[j];
135		for (i in src) {
136			dest[i] = src[i];
137		}
138	}
139	return dest;
140}
141
142// @function create(proto: Object, properties?: Object): Object
143// Compatibility polyfill for [Object.create](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/create)
144var create = Object.create || (function () {
145	function F() {}
146	return function (proto) {
147		F.prototype = proto;
148		return new F();
149	};
150})();
151
152// @function bind(fn: Function, …): Function
153// Returns a new function bound to the arguments passed, like [Function.prototype.bind](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Function/bind).
154// Has a `L.bind()` shortcut.
155function bind(fn, obj) {
156	var slice = Array.prototype.slice;
157
158	if (fn.bind) {
159		return fn.bind.apply(fn, slice.call(arguments, 1));
160	}
161
162	var args = slice.call(arguments, 2);
163
164	return function () {
165		return fn.apply(obj, args.length ? args.concat(slice.call(arguments)) : arguments);
166	};
167}
168
169// @property lastId: Number
170// Last unique ID used by [`stamp()`](#util-stamp)
171var lastId = 0;
172
173// @function stamp(obj: Object): Number
174// Returns the unique ID of an object, assigning it one if it doesn't have it.
175function stamp(obj) {
176	/*eslint-disable */
177	obj._leaflet_id = obj._leaflet_id || ++lastId;
178	return obj._leaflet_id;
179	/* eslint-enable */
180}
181
vendor: 5,772 bytes, lines 182-338
182// @function throttle(fn: Function, time: Number, context: Object): Function
183// Returns a function which executes function `fn` with the given scope `context`
184// (so that the `this` keyword refers to `context` inside `fn`'s code). The function
185// `fn` will be called no more than one time per given amount of `time`. The arguments
186// received by the bound function will be any arguments passed when binding the
187// function, followed by any arguments passed when invoking the bound function.
188// Has an `L.throttle` shortcut.
189function throttle(fn, time, context) {
190	var lock, args, wrapperFn, later;
191
192	later = function () {
193		// reset lock and call if queued
194		lock = false;
195		if (args) {
196			wrapperFn.apply(context, args);
197			args = false;
198		}
199	};
200
201	wrapperFn = function () {
202		if (lock) {
203			// called too soon, queue to call later
204			args = arguments;
205
206		} else {
207			// call and lock until later
208			fn.apply(context, arguments);
209			setTimeout(later, time);
210			lock = true;
211		}
212	};
213
214	return wrapperFn;
215}
216
217// @function wrapNum(num: Number, range: Number[], includeMax?: Boolean): Number
218// Returns the number `num` modulo `range` in such a way so it lies within
219// `range[0]` and `range[1]`. The returned value will be always smaller than
220// `range[1]` unless `includeMax` is set to `true`.
221function wrapNum(x, range, includeMax) {
222	var max = range[1],
223	    min = range[0],
224	    d = max - min;
225	return x === max && includeMax ? x : ((x - min) % d + d) % d + min;
226}
227
228// @function falseFn(): Function
229// Returns a function which always returns `false`.
230function falseFn() { return false; }
231
232// @function formatNum(num: Number, digits?: Number): Number
233// Returns the number `num` rounded to `digits` decimals, or to 6 decimals by default.
234function formatNum(num, digits) {
235	var pow = Math.pow(10, (digits === undefined ? 6 : digits));
236	return Math.round(num * pow) / pow;
237}
238
239// @function trim(str: String): String
240// Compatibility polyfill for [String.prototype.trim](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String/Trim)
241function trim(str) {
242	return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g, '');
243}
244
245// @function splitWords(str: String): String[]
246// Trims and splits the string on whitespace and returns the array of parts.
247function splitWords(str) {
248	return trim(str).split(/\s+/);
249}
250
251// @function setOptions(obj: Object, options: Object): Object
252// Merges the given properties to the `options` of the `obj` object, returning the resulting options. See `Class options`. Has an `L.setOptions` shortcut.
253function setOptions(obj, options) {
254	if (!obj.hasOwnProperty('options')) {
255		obj.options = obj.options ? create(obj.options) : {};
256	}
257	for (var i in options) {
258		obj.options[i] = options[i];
259	}
260	return obj.options;
261}
262
263// @function getParamString(obj: Object, existingUrl?: String, uppercase?: Boolean): String
264// Converts an object into a parameter URL string, e.g. `{a: "foo", b: "bar"}`
265// translates to `'?a=foo&b=bar'`. If `existingUrl` is set, the parameters will
266// be appended at the end. If `uppercase` is `true`, the parameter names will
267// be uppercased (e.g. `'?A=foo&B=bar'`)
268function getParamString(obj, existingUrl, uppercase) {
269	var params = [];
270	for (var i in obj) {
271		params.push(encodeURIComponent(uppercase ? i.toUpperCase() : i) + '=' + encodeURIComponent(obj[i]));
272	}
273	return ((!existingUrl || existingUrl.indexOf('?') === -1) ? '?' : '&') + params.join('&');
274}
275
276var templateRe = /\{ *([\w_-]+) *\}/g;
277
278// @function template(str: String, data: Object): String
279// Simple templating facility, accepts a template string of the form `'Hello {a}, {b}'`
280// and a data object like `{a: 'foo', b: 'bar'}`, returns evaluated string
281// `('Hello foo, bar')`. You can also specify functions instead of strings for
282// data values — they will be evaluated passing `data` as an argument.
283function template(str, data) {
284	return str.replace(templateRe, function (str, key) {
285		var value = data[key];
286
287		if (value === undefined) {
288			throw new Error('No value provided for variable ' + str);
289
290		} else if (typeof value === 'function') {
291			value = value(data);
292		}
293		return value;
294	});
295}
296
297// @function isArray(obj): Boolean
298// Compatibility polyfill for [Array.isArray](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray)
299var isArray = Array.isArray || function (obj) {
300	return (Object.prototype.toString.call(obj) === '[object Array]');
301};
302
303// @function indexOf(array: Array, el: Object): Number
304// Compatibility polyfill for [Array.prototype.indexOf](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf)
305function indexOf(array, el) {
306	for (var i = 0; i < array.length; i++) {
307		if (array[i] === el) { return i; }
308	}
309	return -1;
310}
311
312// @property emptyImageUrl: String
313// Data URI string containing a base64-encoded empty GIF image.
314// Used as a hack to free memory from unused images on WebKit-powered
315// mobile devices (by setting image `src` to this string).
316var emptyImageUrl = 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=';
317
318// inspired by http://paulirish.com/2011/requestanimationframe-for-smart-animating/
319
320function getPrefixed(name) {
321	return window['webkit' + name] || window['moz' + name] || window['ms' + name];
322}
323
324var lastTime = 0;
325
326// fallback for IE 7-8
327function timeoutDefer(fn) {
328	var time = +new Date(),
329	    timeToCall = Math.max(0, 16 - (time - lastTime));
330
331	lastTime = time + timeToCall;
332	return window.setTimeout(fn, timeToCall);
333}
334
335var requestFn = window.requestAnimationFrame || getPrefixed('RequestAnimationFrame') || timeoutDefer;
336var cancelFn = window.cancelAnimationFrame || getPrefixed('CancelAnimationFrame') ||
337		getPrefixed('CancelRequestAnimationFrame') || function (id) { window.clearTimeout(id); };
338
339// @function requestAnimFrame(fn: Function, context?: Object, immediate?: Boolean): Number
340// Schedules `fn` to be executed when the browser repaints. `fn` is bound to
341// `context` if given. When `immediate` is set, `fn` is called immediately if
342// the browser doesn't have native support for
343// [`window.requestAnimationFrame`](https://developer.mozilla.org/docs/Web/API/window/requestAnimationFrame),
344// otherwise it's delayed. Returns a request ID that can be used to cancel the request.
345function requestAnimFrame(fn, context, immediate) {
346	if (immediate && requestFn === timeoutDefer) {
347		fn.call(context);
348	} else {
349		return requestFn.call(window, bind(fn, context));
350	}
351}
352
353// @function cancelAnimFrame(id: Number): undefined
354// Cancels a previous `requestAnimFrame`. See also [window.cancelAnimationFrame](https://developer.mozilla.org/docs/Web/API/window/cancelAnimationFrame).
355function cancelAnimFrame(id) {
356	if (id) {
357		cancelFn.call(window, id);
358	}
359}
360
361
362var Util = (Object.freeze || Object)({
363	freeze: freeze,
364	extend: extend,
365	create: create,
366	bind: bind,
367	lastId: lastId,
368	stamp: stamp,
369	throttle: throttle,
370	wrapNum: wrapNum,
371	falseFn: falseFn,
372	formatNum: formatNum,
373	trim: trim,
374	splitWords: splitWords,
375	setOptions: setOptions,
376	getParamString: getParamString,
377	template: template,
378	isArray: isArray,
379	indexOf: indexOf,
380	emptyImageUrl: emptyImageUrl,
381	requestFn: requestFn,
382	cancelFn: cancelFn,
383	requestAnimFrame: requestAnimFrame,
384	cancelAnimFrame: cancelAnimFrame
385});
386
387// @class Class
388// @aka L.Class
389
390// @section
391// @uninheritable
392
393// Thanks to John Resig and Dean Edwards for inspiration!
394
395function Class() {}
396
397Class.extend = function (props) {
398
399	// @function extend(props: Object): Function
400	// [Extends the current class](#class-inheritance) given the properties to be included.
401	// Returns a Javascript function that is a class constructor (to be called with `new`).
402	var NewClass = function () {
403
404		// call the constructor
405		if (this.initialize) {
406			this.initialize.apply(this, arguments);
407		}
408
409		// call all constructor hooks
410		this.callInitHooks();
411	};
412
413	var parentProto = NewClass.__super__ = this.prototype;
414
415	var proto = create(parentProto);
416	proto.constructor = NewClass;
417
418	NewClass.prototype = proto;
419
420	// inherit parent's statics
421	for (var i in this) {
422		if (this.hasOwnProperty(i) && i !== 'prototype' && i !== '__super__') {
423			NewClass[i] = this[i];
424		}
425	}
426
427	// mix static properties into the class
428	if (props.statics) {
429		extend(NewClass, props.statics);
430		delete props.statics;
431	}
432
433	// mix includes into the prototype
434	if (props.includes) {
435		checkDeprecatedMixinEvents(props.includes);
436		extend.apply(null, [proto].concat(props.includes));
437		delete props.includes;
438	}
439
440	// merge options
441	if (proto.options) {
442		props.options = extend(create(proto.options), props.options);
443	}
444
445	// mix given properties into the prototype
446	extend(proto, props);
447
448	proto._initHooks = [];
449
450	// add method for calling all hooks
451	proto.callInitHooks = function () {
452
453		if (this._initHooksCalled) { return; }
454
455		if (parentProto.callInitHooks) {
456			parentProto.callInitHooks.call(this);
457		}
458
459		this._initHooksCalled = true;
460
461		for (var i = 0, len = proto._initHooks.length; i < len; i++) {
462			proto._initHooks[i].call(this);
463		}
464	};
465
466	return NewClass;
467};
468
469
470// @function include(properties: Object): this
471// [Includes a mixin](#class-includes) into the current class.
472Class.include = function (props) {
473	extend(this.prototype, props);
474	return this;
475};
476
477// @function mergeOptions(options: Object): this
478// [Merges `options`](#class-options) into the defaults of the class.
479Class.mergeOptions = function (options) {
480	extend(this.prototype.options, options);
481	return this;
482};
483
484// @function addInitHook(fn: Function): this
485// Adds a [constructor hook](#class-constructor-hooks) to the class.
486Class.addInitHook = function (fn) { // (Function) || (String, args...)
487	var args = Array.prototype.slice.call(arguments, 1);
488
489	var init = typeof fn === 'function' ? fn : function () {
490		this[fn].apply(this, args);
491	};
492
493	this.prototype._initHooks = this.prototype._initHooks || [];
494	this.prototype._initHooks.push(init);
495	return this;
496};
497
498function checkDeprecatedMixinEvents(includes) {
499	if (typeof L === 'undefined' || !L || !L.Mixin) { return; }
500
501	includes = isArray(includes) ? includes : [includes];
502
503	for (var i = 0; i < includes.length; i++) {
504		if (includes[i] === L.Mixin.Events) {
505			console.warn('Deprecated include of L.Mixin.Events: ' +
506				'this property will be removed in future releases, ' +
507				'please inherit from L.Evented instead.', new Error().stack);
508		}
509	}
510}
511
512/*
513 * @class Evented
514 * @aka L.Evented
515 * @inherits Class
516 *
517 * A set of methods shared between event-powered classes (like `Map` and `Marker`). Generally, events allow you to execute some function when something happens with an object (e.g. the user clicks on the map, causing the map to fire `'click'` event).
518 *
519 * @example
520 *
521 * ```js
522 * map.on('click', function(e) {
523 * 	alert(e.latlng);
524 * } );
525 * ```
526 *
527 * Leaflet deals with event listeners by reference, so if you want to add a listener and then remove it, define it as a function:
528 *
529 * ```js
530 * function onClick(e) { ... }
531 *
532 * map.on('click', onClick);
533 * map.off('click', onClick);
534 * ```
535 */
536
537var Events = {
538	/* @method on(type: String, fn: Function, context?: Object): this
539	 * Adds a listener function (`fn`) to a particular event type of the object. You can optionally specify the context of the listener (object the this keyword will point to). You can also pass several space-separated types (e.g. `'click dblclick'`).
540	 *
541	 * @alternative
542	 * @method on(eventMap: Object): this
543	 * Adds a set of type/listener pairs, e.g. `{click: onClick, mousemove: onMouseMove}`
544	 */
545	on: function (types, fn, context) {
546
547		// types can be a map of types/handlers
548		if (typeof types === 'object') {
549			for (var type in types) {
550				// we don't process space-separated events here for performance;
551				// it's a hot path since Layer uses the on(obj) syntax
552				this._on(type, types[type], fn);
553			}
554
555		} else {
556			// types can be a string of space-separated words
557			types = splitWords(types);
558
559			for (var i = 0, len = types.length; i < len; i++) {
560				this._on(types[i], fn, context);
561			}
562		}
563
564		return this;
565	},
566
567	/* @method off(type: String, fn?: Function, context?: Object): this
568	 * Removes a previously added listener function. If no function is specified, it will remove all the listeners of that particular event from the object. Note that if you passed a custom context to `on`, you must pass the same context to `off` in order to remove the listener.
569	 *
570	 * @alternative
571	 * @method off(eventMap: Object): this
572	 * Removes a set of type/listener pairs.
573	 *
574	 * @alternative
575	 * @method off: this
576	 * Removes all listeners to all events on the object.
577	 */
578	off: function (types, fn, context) {
579
580		if (!types) {
581			// clear all listeners if called without arguments
582			delete this._events;
583
584		} else if (typeof types === 'object') {
585			for (var type in types) {
586				this._off(type, types[type], fn);
587			}
588
589		} else {
590			types = splitWords(types);
591
592			for (var i = 0, len = types.length; i < len; i++) {
593				this._off(types[i], fn, context);
594			}
595		}
596
597		return this;
598	},
599
600	// attach listener (without syntactic sugar now)
601	_on: function (type, fn, context) {
602		this._events = this._events || {};
603
604		/* get/init listeners for type */
605		var typeListeners = this._events[type];
606		if (!typeListeners) {
607			typeListeners = [];
608			this._events[type] = typeListeners;
609		}
610
611		if (context === this) {
612			// Less memory footprint.
613			context = undefined;
614		}
615		var newListener = {fn: fn, ctx: context},
616		    listeners = typeListeners;
617
618		// check if fn already there
619		for (var i = 0, len = listeners.length; i < len; i++) {
620			if (listeners[i].fn === fn && listeners[i].ctx === context) {
621				return;
622			}
623		}
624
625		listeners.push(newListener);
626	},
627
628	_off: function (type, fn, context) {
629		var listeners,
630		    i,
631		    len;
632
633		if (!this._events) { return; }
634
635		listeners = this._events[type];
636
637		if (!listeners) {
638			return;
639		}
640
641		if (!fn) {
642			// Set all removed listeners to noop so they are not called if remove happens in fire
643			for (i = 0, len = listeners.length; i < len; i++) {
644				listeners[i].fn = falseFn;
645			}
646			// clear all listeners for a type if function isn't specified
647			delete this._events[type];
648			return;
649		}
650
651		if (context === this) {
652			context = undefined;
653		}
654
655		if (listeners) {
656
657			// find fn and remove it
658			for (i = 0, len = listeners.length; i < len; i++) {
659				var l = listeners[i];
660				if (l.ctx !== context) { continue; }
661				if (l.fn === fn) {
662
663					// set the removed listener to noop so that's not called if remove happens in fire
664					l.fn = falseFn;
665
666					if (this._firingCount) {
667						/* copy array in case events are being fired */
668						this._events[type] = listeners = listeners.slice();
669					}
670					listeners.splice(i, 1);
671
672					return;
673				}
674			}
675		}
676	},
677
678	// @method fire(type: String, data?: Object, propagate?: Boolean): this
679	// Fires an event of the specified type. You can optionally provide an data
680	// object — the first argument of the listener function will contain its
681	// properties. The event can optionally be propagated to event parents.
682	fire: function (type, data, propagate) {
vendor: 16,671 bytes, lines 683-1300
683		if (!this.listens(type, propagate)) { return this; }
684
685		var event = extend({}, data, {
686			type: type,
687			target: this,
688			sourceTarget: data && data.sourceTarget || this
689		});
690
691		if (this._events) {
692			var listeners = this._events[type];
693
694			if (listeners) {
695				this._firingCount = (this._firingCount + 1) || 1;
696				for (var i = 0, len = listeners.length; i < len; i++) {
697					var l = listeners[i];
698					l.fn.call(l.ctx || this, event);
699				}
700
701				this._firingCount--;
702			}
703		}
704
705		if (propagate) {
706			// propagate the event to parents (set with addEventParent)
707			this._propagateEvent(event);
708		}
709
710		return this;
711	},
712
713	// @method listens(type: String): Boolean
714	// Returns `true` if a particular event type has any listeners attached to it.
715	listens: function (type, propagate) {
716		var listeners = this._events && this._events[type];
717		if (listeners && listeners.length) { return true; }
718
719		if (propagate) {
720			// also check parents for listeners if event propagates
721			for (var id in this._eventParents) {
722				if (this._eventParents[id].listens(type, propagate)) { return true; }
723			}
724		}
725		return false;
726	},
727
728	// @method once(…): this
729	// Behaves as [`on(…)`](#evented-on), except the listener will only get fired once and then removed.
730	once: function (types, fn, context) {
731
732		if (typeof types === 'object') {
733			for (var type in types) {
734				this.once(type, types[type], fn);
735			}
736			return this;
737		}
738
739		var handler = bind(function () {
740			this
741			    .off(types, fn, context)
742			    .off(types, handler, context);
743		}, this);
744
745		// add a listener that's executed once and removed after that
746		return this
747		    .on(types, fn, context)
748		    .on(types, handler, context);
749	},
750
751	// @method addEventParent(obj: Evented): this
752	// Adds an event parent - an `Evented` that will receive propagated events
753	addEventParent: function (obj) {
754		this._eventParents = this._eventParents || {};
755		this._eventParents[stamp(obj)] = obj;
756		return this;
757	},
758
759	// @method removeEventParent(obj: Evented): this
760	// Removes an event parent, so it will stop receiving propagated events
761	removeEventParent: function (obj) {
762		if (this._eventParents) {
763			delete this._eventParents[stamp(obj)];
764		}
765		return this;
766	},
767
768	_propagateEvent: function (e) {
769		for (var id in this._eventParents) {
770			this._eventParents[id].fire(e.type, extend({
771				layer: e.target,
772				propagatedFrom: e.target
773			}, e), true);
774		}
775	}
776};
777
778// aliases; we should ditch those eventually
779
780// @method addEventListener(…): this
781// Alias to [`on(…)`](#evented-on)
782Events.addEventListener = Events.on;
783
784// @method removeEventListener(…): this
785// Alias to [`off(…)`](#evented-off)
786
787// @method clearAllEventListeners(…): this
788// Alias to [`off()`](#evented-off)
789Events.removeEventListener = Events.clearAllEventListeners = Events.off;
790
791// @method addOneTimeEventListener(…): this
792// Alias to [`once(…)`](#evented-once)
793Events.addOneTimeEventListener = Events.once;
794
795// @method fireEvent(…): this
796// Alias to [`fire(…)`](#evented-fire)
797Events.fireEvent = Events.fire;
798
799// @method hasEventListeners(…): Boolean
800// Alias to [`listens(…)`](#evented-listens)
801Events.hasEventListeners = Events.listens;
802
803var Evented = Class.extend(Events);
804
805/*
806 * @class Point
807 * @aka L.Point
808 *
809 * Represents a point with `x` and `y` coordinates in pixels.
810 *
811 * @example
812 *
813 * ```js
814 * var point = L.point(200, 300);
815 * ```
816 *
817 * All Leaflet methods and options that accept `Point` objects also accept them in a simple Array form (unless noted otherwise), so these lines are equivalent:
818 *
819 * ```js
820 * map.panBy([200, 300]);
821 * map.panBy(L.point(200, 300));
822 * ```
823 *
824 * Note that `Point` does not inherit from Leafet's `Class` object,
825 * which means new classes can't inherit from it, and new methods
826 * can't be added to it with the `include` function.
827 */
828
829function Point(x, y, round) {
830	// @property x: Number; The `x` coordinate of the point
831	this.x = (round ? Math.round(x) : x);
832	// @property y: Number; The `y` coordinate of the point
833	this.y = (round ? Math.round(y) : y);
834}
835
836var trunc = Math.trunc || function (v) {
837	return v > 0 ? Math.floor(v) : Math.ceil(v);
838};
839
840Point.prototype = {
841
842	// @method clone(): Point
843	// Returns a copy of the current point.
844	clone: function () {
845		return new Point(this.x, this.y);
846	},
847
848	// @method add(otherPoint: Point): Point
849	// Returns the result of addition of the current and the given points.
850	add: function (point) {
851		// non-destructive, returns a new point
852		return this.clone()._add(toPoint(point));
853	},
854
855	_add: function (point) {
856		// destructive, used directly for performance in situations where it's safe to modify existing point
857		this.x += point.x;
858		this.y += point.y;
859		return this;
860	},
861
862	// @method subtract(otherPoint: Point): Point
863	// Returns the result of subtraction of the given point from the current.
864	subtract: function (point) {
865		return this.clone()._subtract(toPoint(point));
866	},
867
868	_subtract: function (point) {
869		this.x -= point.x;
870		this.y -= point.y;
871		return this;
872	},
873
874	// @method divideBy(num: Number): Point
875	// Returns the result of division of the current point by the given number.
876	divideBy: function (num) {
877		return this.clone()._divideBy(num);
878	},
879
880	_divideBy: function (num) {
881		this.x /= num;
882		this.y /= num;
883		return this;
884	},
885
886	// @method multiplyBy(num: Number): Point
887	// Returns the result of multiplication of the current point by the given number.
888	multiplyBy: function (num) {
889		return this.clone()._multiplyBy(num);
890	},
891
892	_multiplyBy: function (num) {
893		this.x *= num;
894		this.y *= num;
895		return this;
896	},
897
898	// @method scaleBy(scale: Point): Point
899	// Multiply each coordinate of the current point by each coordinate of
900	// `scale`. In linear algebra terms, multiply the point by the
901	// [scaling matrix](https://en.wikipedia.org/wiki/Scaling_%28geometry%29#Matrix_representation)
902	// defined by `scale`.
903	scaleBy: function (point) {
904		return new Point(this.x * point.x, this.y * point.y);
905	},
906
907	// @method unscaleBy(scale: Point): Point
908	// Inverse of `scaleBy`. Divide each coordinate of the current point by
909	// each coordinate of `scale`.
910	unscaleBy: function (point) {
911		return new Point(this.x / point.x, this.y / point.y);
912	},
913
914	// @method round(): Point
915	// Returns a copy of the current point with rounded coordinates.
916	round: function () {
917		return this.clone()._round();
918	},
919
920	_round: function () {
921		this.x = Math.round(this.x);
922		this.y = Math.round(this.y);
923		return this;
924	},
925
926	// @method floor(): Point
927	// Returns a copy of the current point with floored coordinates (rounded down).
928	floor: function () {
929		return this.clone()._floor();
930	},
931
932	_floor: function () {
933		this.x = Math.floor(this.x);
934		this.y = Math.floor(this.y);
935		return this;
936	},
937
938	// @method ceil(): Point
939	// Returns a copy of the current point with ceiled coordinates (rounded up).
940	ceil: function () {
941		return this.clone()._ceil();
942	},
943
944	_ceil: function () {
945		this.x = Math.ceil(this.x);
946		this.y = Math.ceil(this.y);
947		return this;
948	},
949
950	// @method trunc(): Point
951	// Returns a copy of the current point with truncated coordinates (rounded towards zero).
952	trunc: function () {
953		return this.clone()._trunc();
954	},
955
956	_trunc: function () {
957		this.x = trunc(this.x);
958		this.y = trunc(this.y);
959		return this;
960	},
961
962	// @method distanceTo(otherPoint: Point): Number
963	// Returns the cartesian distance between the current and the given points.
964	distanceTo: function (point) {
965		point = toPoint(point);
966
967		var x = point.x - this.x,
968		    y = point.y - this.y;
969
970		return Math.sqrt(x * x + y * y);
971	},
972
973	// @method equals(otherPoint: Point): Boolean
974	// Returns `true` if the given point has the same coordinates.
975	equals: function (point) {
976		point = toPoint(point);
977
978		return point.x === this.x &&
979		       point.y === this.y;
980	},
981
982	// @method contains(otherPoint: Point): Boolean
983	// Returns `true` if both coordinates of the given point are less than the corresponding current point coordinates (in absolute values).
984	contains: function (point) {
985		point = toPoint(point);
986
987		return Math.abs(point.x) <= Math.abs(this.x) &&
988		       Math.abs(point.y) <= Math.abs(this.y);
989	},
990
991	// @method toString(): String
992	// Returns a string representation of the point for debugging purposes.
993	toString: function () {
994		return 'Point(' +
995		        formatNum(this.x) + ', ' +
996		        formatNum(this.y) + ')';
997	}
998};
999
1000// @factory L.point(x: Number, y: Number, round?: Boolean)
1001// Creates a Point object with the given `x` and `y` coordinates. If optional `round` is set to true, rounds the `x` and `y` values.
1002
1003// @alternative
1004// @factory L.point(coords: Number[])
1005// Expects an array of the form `[x, y]` instead.
1006
1007// @alternative
1008// @factory L.point(coords: Object)
1009// Expects a plain object of the form `{x: Number, y: Number}` instead.
1010function toPoint(x, y, round) {
1011	if (x instanceof Point) {
1012		return x;
1013	}
1014	if (isArray(x)) {
1015		return new Point(x[0], x[1]);
1016	}
1017	if (x === undefined || x === null) {
1018		return x;
1019	}
1020	if (typeof x === 'object' && 'x' in x && 'y' in x) {
1021		return new Point(x.x, x.y);
1022	}
1023	return new Point(x, y, round);
1024}
1025
1026/*
1027 * @class Bounds
1028 * @aka L.Bounds
1029 *
1030 * Represents a rectangular area in pixel coordinates.
1031 *
1032 * @example
1033 *
1034 * ```js
1035 * var p1 = L.point(10, 10),
1036 * p2 = L.point(40, 60),
1037 * bounds = L.bounds(p1, p2);
1038 * ```
1039 *
1040 * All Leaflet methods that accept `Bounds` objects also accept them in a simple Array form (unless noted otherwise), so the bounds example above can be passed like this:
1041 *
1042 * ```js
1043 * otherBounds.intersects([[10, 10], [40, 60]]);
1044 * ```
1045 *
1046 * Note that `Bounds` does not inherit from Leafet's `Class` object,
1047 * which means new classes can't inherit from it, and new methods
1048 * can't be added to it with the `include` function.
1049 */
1050
1051function Bounds(a, b) {
1052	if (!a) { return; }
1053
1054	var points = b ? [a, b] : a;
1055
1056	for (var i = 0, len = points.length; i < len; i++) {
1057		this.extend(points[i]);
1058	}
1059}
1060
1061Bounds.prototype = {
1062	// @method extend(point: Point): this
1063	// Extends the bounds to contain the given point.
1064	extend: function (point) { // (Point)
1065		point = toPoint(point);
1066
1067		// @property min: Point
1068		// The top left corner of the rectangle.
1069		// @property max: Point
1070		// The bottom right corner of the rectangle.
1071		if (!this.min && !this.max) {
1072			this.min = point.clone();
1073			this.max = point.clone();
1074		} else {
1075			this.min.x = Math.min(point.x, this.min.x);
1076			this.max.x = Math.max(point.x, this.max.x);
1077			this.min.y = Math.min(point.y, this.min.y);
1078			this.max.y = Math.max(point.y, this.max.y);
1079		}
1080		return this;
1081	},
1082
1083	// @method getCenter(round?: Boolean): Point
1084	// Returns the center point of the bounds.
1085	getCenter: function (round) {
1086		return new Point(
1087		        (this.min.x + this.max.x) / 2,
1088		        (this.min.y + this.max.y) / 2, round);
1089	},
1090
1091	// @method getBottomLeft(): Point
1092	// Returns the bottom-left point of the bounds.
1093	getBottomLeft: function () {
1094		return new Point(this.min.x, this.max.y);
1095	},
1096
1097	// @method getTopRight(): Point
1098	// Returns the top-right point of the bounds.
1099	getTopRight: function () { // -> Point
1100		return new Point(this.max.x, this.min.y);
1101	},
1102
1103	// @method getTopLeft(): Point
1104	// Returns the top-left point of the bounds (i.e. [`this.min`](#bounds-min)).
1105	getTopLeft: function () {
1106		return this.min; // left, top
1107	},
1108
1109	// @method getBottomRight(): Point
1110	// Returns the bottom-right point of the bounds (i.e. [`this.max`](#bounds-max)).
1111	getBottomRight: function () {
1112		return this.max; // right, bottom
1113	},
1114
1115	// @method getSize(): Point
1116	// Returns the size of the given bounds
1117	getSize: function () {
1118		return this.max.subtract(this.min);
1119	},
1120
1121	// @method contains(otherBounds: Bounds): Boolean
1122	// Returns `true` if the rectangle contains the given one.
1123	// @alternative
1124	// @method contains(point: Point): Boolean
1125	// Returns `true` if the rectangle contains the given point.
1126	contains: function (obj) {
1127		var min, max;
1128
1129		if (typeof obj[0] === 'number' || obj instanceof Point) {
1130			obj = toPoint(obj);
1131		} else {
1132			obj = toBounds(obj);
1133		}
1134
1135		if (obj instanceof Bounds) {
1136			min = obj.min;
1137			max = obj.max;
1138		} else {
1139			min = max = obj;
1140		}
1141
1142		return (min.x >= this.min.x) &&
1143		       (max.x <= this.max.x) &&
1144		       (min.y >= this.min.y) &&
1145		       (max.y <= this.max.y);
1146	},
1147
1148	// @method intersects(otherBounds: Bounds): Boolean
1149	// Returns `true` if the rectangle intersects the given bounds. Two bounds
1150	// intersect if they have at least one point in common.
1151	intersects: function (bounds) { // (Bounds) -> Boolean
1152		bounds = toBounds(bounds);
1153
1154		var min = this.min,
1155		    max = this.max,
1156		    min2 = bounds.min,
1157		    max2 = bounds.max,
1158		    xIntersects = (max2.x >= min.x) && (min2.x <= max.x),
1159		    yIntersects = (max2.y >= min.y) && (min2.y <= max.y);
1160
1161		return xIntersects && yIntersects;
1162	},
1163
1164	// @method overlaps(otherBounds: Bounds): Boolean
1165	// Returns `true` if the rectangle overlaps the given bounds. Two bounds
1166	// overlap if their intersection is an area.
1167	overlaps: function (bounds) { // (Bounds) -> Boolean
1168		bounds = toBounds(bounds);
1169
1170		var min = this.min,
1171		    max = this.max,
1172		    min2 = bounds.min,
1173		    max2 = bounds.max,
1174		    xOverlaps = (max2.x > min.x) && (min2.x < max.x),
1175		    yOverlaps = (max2.y > min.y) && (min2.y < max.y);
1176
1177		return xOverlaps && yOverlaps;
1178	},
1179
1180	isValid: function () {
1181		return !!(this.min && this.max);
1182	}
1183};
1184
1185
1186// @factory L.bounds(corner1: Point, corner2: Point)
1187// Creates a Bounds object from two corners coordinate pairs.
1188// @alternative
1189// @factory L.bounds(points: Point[])
1190// Creates a Bounds object from the given array of points.
1191function toBounds(a, b) {
1192	if (!a || a instanceof Bounds) {
1193		return a;
1194	}
1195	return new Bounds(a, b);
1196}
1197
1198/*
1199 * @class LatLngBounds
1200 * @aka L.LatLngBounds
1201 *
1202 * Represents a rectangular geographical area on a map.
1203 *
1204 * @example
1205 *
1206 * ```js
1207 * var corner1 = L.latLng(40.712, -74.227),
1208 * corner2 = L.latLng(40.774, -74.125),
1209 * bounds = L.latLngBounds(corner1, corner2);
1210 * ```
1211 *
1212 * All Leaflet methods that accept LatLngBounds objects also accept them in a simple Array form (unless noted otherwise), so the bounds example above can be passed like this:
1213 *
1214 * ```js
1215 * map.fitBounds([
1216 * 	[40.712, -74.227],
1217 * 	[40.774, -74.125]
1218 * ]);
1219 * ```
1220 *
1221 * Caution: if the area crosses the antimeridian (often confused with the International Date Line), you must specify corners _outside_ the [-180, 180] degrees longitude range.
1222 *
1223 * Note that `LatLngBounds` does not inherit from Leafet's `Class` object,
1224 * which means new classes can't inherit from it, and new methods
1225 * can't be added to it with the `include` function.
1226 */
1227
1228function LatLngBounds(corner1, corner2) { // (LatLng, LatLng) or (LatLng[])
1229	if (!corner1) { return; }
1230
1231	var latlngs = corner2 ? [corner1, corner2] : corner1;
1232
1233	for (var i = 0, len = latlngs.length; i < len; i++) {
1234		this.extend(latlngs[i]);
1235	}
1236}
1237
1238LatLngBounds.prototype = {
1239
1240	// @method extend(latlng: LatLng): this
1241	// Extend the bounds to contain the given point
1242
1243	// @alternative
1244	// @method extend(otherBounds: LatLngBounds): this
1245	// Extend the bounds to contain the given bounds
1246	extend: function (obj) {
1247		var sw = this._southWest,
1248		    ne = this._northEast,
1249		    sw2, ne2;
1250
1251		if (obj instanceof LatLng) {
1252			sw2 = obj;
1253			ne2 = obj;
1254
1255		} else if (obj instanceof LatLngBounds) {
1256			sw2 = obj._southWest;
1257			ne2 = obj._northEast;
1258
1259			if (!sw2 || !ne2) { return this; }
1260
1261		} else {
1262			return obj ? this.extend(toLatLng(obj) || toLatLngBounds(obj)) : this;
1263		}
1264
1265		if (!sw && !ne) {
1266			this._southWest = new LatLng(sw2.lat, sw2.lng);
1267			this._northEast = new LatLng(ne2.lat, ne2.lng);
1268		} else {
1269			sw.lat = Math.min(sw2.lat, sw.lat);
1270			sw.lng = Math.min(sw2.lng, sw.lng);
1271			ne.lat = Math.max(ne2.lat, ne.lat);
1272			ne.lng = Math.max(ne2.lng, ne.lng);
1273		}
1274
1275		return this;
1276	},
1277
1278	// @method pad(bufferRatio: Number): LatLngBounds
1279	// Returns bounds created by extending or retracting the current bounds by a given ratio in each direction.
1280	// For example, a ratio of 0.5 extends the bounds by 50% in each direction.
1281	// Negative values will retract the bounds.
1282	pad: function (bufferRatio) {
1283		var sw = this._southWest,
1284		    ne = this._northEast,
1285		    heightBuffer = Math.abs(sw.lat - ne.lat) * bufferRatio,
1286		    widthBuffer = Math.abs(sw.lng - ne.lng) * bufferRatio;
1287
1288		return new LatLngBounds(
1289		        new LatLng(sw.lat - heightBuffer, sw.lng - widthBuffer),
1290		        new LatLng(ne.lat + heightBuffer, ne.lng + widthBuffer));
1291	},
1292
1293	// @method getCenter(): LatLng
1294	// Returns the center point of the bounds.
1295	getCenter: function () {
1296		return new LatLng(
1297		        (this._southWest.lat + this._northEast.lat) / 2,
1298		        (this._southWest.lng + this._northEast.lng) / 2);
1299	},
1300
1301	// @method getSouthWest(): LatLng
1302	// Returns the south-west point of the bounds.
1303	getSouthWest: function () {
1304		return this._southWest;
1305	},
1306
1307	// @method getNorthEast(): LatLng
1308	// Returns the north-east point of the bounds.
1309	getNorthEast: function () {
1310		return this._northEast;
1311	},
1312
1313	// @method getNorthWest(): LatLng
1314	// Returns the north-west point of the bounds.
1315	getNorthWest: function () {
1316		return new LatLng(this.getNorth(), this.getWest());
1317	},
1318
1319	// @method getSouthEast(): LatLng
1320	// Returns the south-east point of the bounds.
1321	getSouthEast: function () {
1322		return new LatLng(this.getSouth(), this.getEast());
1323	},
1324
1325	// @method getWest(): Number
1326	// Returns the west longitude of the bounds
1327	getWest: function () {
1328		return this._southWest.lng;
1329	},
1330
1331	// @method getSouth(): Number
1332	// Returns the south latitude of the bounds
1333	getSouth: function () {
1334		return this._southWest.lat;
1335	},
1336
1337	// @method getEast(): Number
1338	// Returns the east longitude of the bounds
1339	getEast: function () {
1340		return this._northEast.lng;
1341	},
1342
1343	// @method getNorth(): Number
1344	// Returns the north latitude of the bounds
1345	getNorth: function () {
1346		return this._northEast.lat;
1347	},
1348
1349	// @method contains(otherBounds: LatLngBounds): Boolean
1350	// Returns `true` if the rectangle contains the given one.
1351
1352	// @alternative
1353	// @method contains (latlng: LatLng): Boolean
1354	// Returns `true` if the rectangle contains the given point.
1355	contains: function (obj) { // (LatLngBounds) or (LatLng) -> Boolean
1356		if (typeof obj[0] === 'number' || obj instanceof LatLng || 'lat' in obj) {
1357			obj = toLatLng(obj);
1358		} else {
1359			obj = toLatLngBounds(obj);
1360		}
1361
1362		var sw = this._southWest,
1363		    ne = this._northEast,
1364		    sw2, ne2;
1365
1366		if (obj instanceof LatLngBounds) {
vendor: 7,059 bytes, lines 1367-1586
1367			sw2 = obj.getSouthWest();
1368			ne2 = obj.getNorthEast();
1369		} else {
1370			sw2 = ne2 = obj;
1371		}
1372
1373		return (sw2.lat >= sw.lat) && (ne2.lat <= ne.lat) &&
1374		       (sw2.lng >= sw.lng) && (ne2.lng <= ne.lng);
1375	},
1376
1377	// @method intersects(otherBounds: LatLngBounds): Boolean
1378	// Returns `true` if the rectangle intersects the given bounds. Two bounds intersect if they have at least one point in common.
1379	intersects: function (bounds) {
1380		bounds = toLatLngBounds(bounds);
1381
1382		var sw = this._southWest,
1383		    ne = this._northEast,
1384		    sw2 = bounds.getSouthWest(),
1385		    ne2 = bounds.getNorthEast(),
1386
1387		    latIntersects = (ne2.lat >= sw.lat) && (sw2.lat <= ne.lat),
1388		    lngIntersects = (ne2.lng >= sw.lng) && (sw2.lng <= ne.lng);
1389
1390		return latIntersects && lngIntersects;
1391	},
1392
1393	// @method overlaps(otherBounds: Bounds): Boolean
1394	// Returns `true` if the rectangle overlaps the given bounds. Two bounds overlap if their intersection is an area.
1395	overlaps: function (bounds) {
1396		bounds = toLatLngBounds(bounds);
1397
1398		var sw = this._southWest,
1399		    ne = this._northEast,
1400		    sw2 = bounds.getSouthWest(),
1401		    ne2 = bounds.getNorthEast(),
1402
1403		    latOverlaps = (ne2.lat > sw.lat) && (sw2.lat < ne.lat),
1404		    lngOverlaps = (ne2.lng > sw.lng) && (sw2.lng < ne.lng);
1405
1406		return latOverlaps && lngOverlaps;
1407	},
1408
1409	// @method toBBoxString(): String
1410	// Returns a string with bounding box coordinates in a 'southwest_lng,southwest_lat,northeast_lng,northeast_lat' format. Useful for sending requests to web services that return geo data.
1411	toBBoxString: function () {
1412		return [this.getWest(), this.getSouth(), this.getEast(), this.getNorth()].join(',');
1413	},
1414
1415	// @method equals(otherBounds: LatLngBounds, maxMargin?: Number): Boolean
1416	// Returns `true` if the rectangle is equivalent (within a small margin of error) to the given bounds. The margin of error can be overridden by setting `maxMargin` to a small number.
1417	equals: function (bounds, maxMargin) {
1418		if (!bounds) { return false; }
1419
1420		bounds = toLatLngBounds(bounds);
1421
1422		return this._southWest.equals(bounds.getSouthWest(), maxMargin) &&
1423		       this._northEast.equals(bounds.getNorthEast(), maxMargin);
1424	},
1425
1426	// @method isValid(): Boolean
1427	// Returns `true` if the bounds are properly initialized.
1428	isValid: function () {
1429		return !!(this._southWest && this._northEast);
1430	}
1431};
1432
1433// TODO International date line?
1434
1435// @factory L.latLngBounds(corner1: LatLng, corner2: LatLng)
1436// Creates a `LatLngBounds` object by defining two diagonally opposite corners of the rectangle.
1437
1438// @alternative
1439// @factory L.latLngBounds(latlngs: LatLng[])
1440// Creates a `LatLngBounds` object defined by the geographical points it contains. Very useful for zooming the map to fit a particular set of locations with [`fitBounds`](#map-fitbounds).
1441function toLatLngBounds(a, b) {
1442	if (a instanceof LatLngBounds) {
1443		return a;
1444	}
1445	return new LatLngBounds(a, b);
1446}
1447
1448/* @class LatLng
1449 * @aka L.LatLng
1450 *
1451 * Represents a geographical point with a certain latitude and longitude.
1452 *
1453 * @example
1454 *
1455 * ```
1456 * var latlng = L.latLng(50.5, 30.5);
1457 * ```
1458 *
1459 * All Leaflet methods that accept LatLng objects also accept them in a simple Array form and simple object form (unless noted otherwise), so these lines are equivalent:
1460 *
1461 * ```
1462 * map.panTo([50, 30]);
1463 * map.panTo({lon: 30, lat: 50});
1464 * map.panTo({lat: 50, lng: 30});
1465 * map.panTo(L.latLng(50, 30));
1466 * ```
1467 *
1468 * Note that `LatLng` does not inherit from Leaflet's `Class` object,
1469 * which means new classes can't inherit from it, and new methods
1470 * can't be added to it with the `include` function.
1471 */
1472
1473function LatLng(lat, lng, alt) {
1474	if (isNaN(lat) || isNaN(lng)) {
1475		throw new Error('Invalid LatLng object: (' + lat + ', ' + lng + ')');
1476	}
1477
1478	// @property lat: Number
1479	// Latitude in degrees
1480	this.lat = +lat;
1481
1482	// @property lng: Number
1483	// Longitude in degrees
1484	this.lng = +lng;
1485
1486	// @property alt: Number
1487	// Altitude in meters (optional)
1488	if (alt !== undefined) {
1489		this.alt = +alt;
1490	}
1491}
1492
1493LatLng.prototype = {
1494	// @method equals(otherLatLng: LatLng, maxMargin?: Number): Boolean
1495	// Returns `true` if the given `LatLng` point is at the same position (within a small margin of error). The margin of error can be overridden by setting `maxMargin` to a small number.
1496	equals: function (obj, maxMargin) {
1497		if (!obj) { return false; }
1498
1499		obj = toLatLng(obj);
1500
1501		var margin = Math.max(
1502		        Math.abs(this.lat - obj.lat),
1503		        Math.abs(this.lng - obj.lng));
1504
1505		return margin <= (maxMargin === undefined ? 1.0E-9 : maxMargin);
1506	},
1507
1508	// @method toString(): String
1509	// Returns a string representation of the point (for debugging purposes).
1510	toString: function (precision) {
1511		return 'LatLng(' +
1512		        formatNum(this.lat, precision) + ', ' +
1513		        formatNum(this.lng, precision) + ')';
1514	},
1515
1516	// @method distanceTo(otherLatLng: LatLng): Number
1517	// Returns the distance (in meters) to the given `LatLng` calculated using the [Spherical Law of Cosines](https://en.wikipedia.org/wiki/Spherical_law_of_cosines).
1518	distanceTo: function (other) {
1519		return Earth.distance(this, toLatLng(other));
1520	},
1521
1522	// @method wrap(): LatLng
1523	// Returns a new `LatLng` object with the longitude wrapped so it's always between -180 and +180 degrees.
1524	wrap: function () {
1525		return Earth.wrapLatLng(this);
1526	},
1527
1528	// @method toBounds(sizeInMeters: Number): LatLngBounds
1529	// Returns a new `LatLngBounds` object in which each boundary is `sizeInMeters/2` meters apart from the `LatLng`.
1530	toBounds: function (sizeInMeters) {
1531		var latAccuracy = 180 * sizeInMeters / 40075017,
1532		    lngAccuracy = latAccuracy / Math.cos((Math.PI / 180) * this.lat);
1533
1534		return toLatLngBounds(
1535		        [this.lat - latAccuracy, this.lng - lngAccuracy],
1536		        [this.lat + latAccuracy, this.lng + lngAccuracy]);
1537	},
1538
1539	clone: function () {
1540		return new LatLng(this.lat, this.lng, this.alt);
1541	}
1542};
1543
1544
1545
1546// @factory L.latLng(latitude: Number, longitude: Number, altitude?: Number): LatLng
1547// Creates an object representing a geographical point with the given latitude and longitude (and optionally altitude).
1548
1549// @alternative
1550// @factory L.latLng(coords: Array): LatLng
1551// Expects an array of the form `[Number, Number]` or `[Number, Number, Number]` instead.
1552
1553// @alternative
1554// @factory L.latLng(coords: Object): LatLng
1555// Expects an plain object of the form `{lat: Number, lng: Number}` or `{lat: Number, lng: Number, alt: Number}` instead.
1556
1557function toLatLng(a, b, c) {
1558	if (a instanceof LatLng) {
1559		return a;
1560	}
1561	if (isArray(a) && typeof a[0] !== 'object') {
1562		if (a.length === 3) {
1563			return new LatLng(a[0], a[1], a[2]);
1564		}
1565		if (a.length === 2) {
1566			return new LatLng(a[0], a[1]);
1567		}
1568		return null;
1569	}
1570	if (a === undefined || a === null) {
1571		return a;
1572	}
1573	if (typeof a === 'object' && 'lat' in a) {
1574		return new LatLng(a.lat, 'lng' in a ? a.lng : a.lon, a.alt);
1575	}
1576	if (b === undefined) {
1577		return null;
1578	}
1579	return new LatLng(a, b, c);
1580}
1581
1582/*
1583 * @namespace CRS
1584 * @crs L.CRS.Base
1585 * Object that defines coordinate reference systems for projecting
1586 * geographical points into pixel (screen) coordinates and back (and to
1587 * coordinates in other units for [WMS](https://en.wikipedia.org/wiki/Web_Map_Service) services). See
1588 * [spatial reference system](http://en.wikipedia.org/wiki/Coordinate_reference_system).
1589 *
1590 * Leaflet defines the most usual CRSs by default. If you want to use a
1591 * CRS not defined by default, take a look at the
1592 * [Proj4Leaflet](https://github.com/kartena/Proj4Leaflet) plugin.
1593 *
1594 * Note that the CRS instances do not inherit from Leafet's `Class` object,
1595 * and can't be instantiated. Also, new classes can't inherit from them,
1596 * and methods can't be added to them with the `include` function.
1597 */
1598
1599var CRS = {
1600	// @method latLngToPoint(latlng: LatLng, zoom: Number): Point
1601	// Projects geographical coordinates into pixel coordinates for a given zoom.
1602	latLngToPoint: function (latlng, zoom) {
1603		var projectedPoint = this.projection.project(latlng),
1604		    scale = this.scale(zoom);
1605
1606		return this.transformation._transform(projectedPoint, scale);
1607	},
1608
1609	// @method pointToLatLng(point: Point, zoom: Number): LatLng
1610	// The inverse of `latLngToPoint`. Projects pixel coordinates on a given
1611	// zoom into geographical coordinates.
1612	pointToLatLng: function (point, zoom) {
1613		var scale = this.scale(zoom),
1614		    untransformedPoint = this.transformation.untransform(point, scale);
1615
1616		return this.projection.unproject(untransformedPoint);
1617	},
1618
1619	// @method project(latlng: LatLng): Point
1620	// Projects geographical coordinates into coordinates in units accepted for
1621	// this CRS (e.g. meters for EPSG:3857, for passing it to WMS services).
1622	project: function (latlng) {
1623		return this.projection.project(latlng);
1624	},
1625
1626	// @method unproject(point: Point): LatLng
1627	// Given a projected coordinate returns the corresponding LatLng.
1628	// The inverse of `project`.
1629	unproject: function (point) {
1630		return this.projection.unproject(point);
1631	},
1632
1633	// @method scale(zoom: Number): Number
1634	// Returns the scale used when transforming projected coordinates into
1635	// pixel coordinates for a particular zoom. For example, it returns
1636	// `256 * 2^zoom` for Mercator-based CRS.
1637	scale: function (zoom) {
1638		return 256 * Math.pow(2, zoom);
1639	},
1640
1641	// @method zoom(scale: Number): Number
1642	// Inverse of `scale()`, returns the zoom level corresponding to a scale
1643	// factor of `scale`.
1644	zoom: function (scale) {
1645		return Math.log(scale / 256) / Math.LN2;
1646	},
1647
1648	// @method getProjectedBounds(zoom: Number): Bounds
1649	// Returns the projection's bounds scaled and transformed for the provided `zoom`.
1650	getProjectedBounds: function (zoom) {
1651		if (this.infinite) { return null; }
1652
1653		var b = this.projection.bounds,
1654		    s = this.scale(zoom),
1655		    min = this.transformation.transform(b.min, s),
1656		    max = this.transformation.transform(b.max, s);
1657
1658		return new Bounds(min, max);
1659	},
1660
1661	// @method distance(latlng1: LatLng, latlng2: LatLng): Number
1662	// Returns the distance between two geographical coordinates.
1663
1664	// @property code: String
1665	// Standard code name of the CRS passed into WMS services (e.g. `'EPSG:3857'`)
1666	//
1667	// @property wrapLng: Number[]
1668	// An array of two numbers defining whether the longitude (horizontal) coordinate
1669	// axis wraps around a given range and how. Defaults to `[-180, 180]` in most
1670	// geographical CRSs. If `undefined`, the longitude axis does not wrap around.
1671	//
1672	// @property wrapLat: Number[]
1673	// Like `wrapLng`, but for the latitude (vertical) axis.
1674
1675	// wrapLng: [min, max],
1676	// wrapLat: [min, max],
1677
1678	// @property infinite: Boolean
1679	// If true, the coordinate space will be unbounded (infinite in both axes)
1680	infinite: false,
1681
1682	// @method wrapLatLng(latlng: LatLng): LatLng
1683	// Returns a `LatLng` where lat and lng has been wrapped according to the
1684	// CRS's `wrapLat` and `wrapLng` properties, if they are outside the CRS's bounds.
1685	wrapLatLng: function (latlng) {
1686		var lng = this.wrapLng ? wrapNum(latlng.lng, this.wrapLng, true) : latlng.lng,
1687		    lat = this.wrapLat ? wrapNum(latlng.lat, this.wrapLat, true) : latlng.lat,
1688		    alt = latlng.alt;
1689
1690		return new LatLng(lat, lng, alt);
1691	},
1692
1693	// @method wrapLatLngBounds(bounds: LatLngBounds): LatLngBounds
1694	// Returns a `LatLngBounds` with the same size as the given one, ensuring
1695	// that its center is within the CRS's bounds.
1696	// Only accepts actual `L.LatLngBounds` instances, not arrays.
1697	wrapLatLngBounds: function (bounds) {
1698		var center = bounds.getCenter(),
1699		    newCenter = this.wrapLatLng(center),
1700		    latShift = center.lat - newCenter.lat,
1701		    lngShift = center.lng - newCenter.lng;
1702
1703		if (latShift === 0 && lngShift === 0) {
1704			return bounds;
1705		}
1706
vendor: 8,558 bytes, lines 1707-1983
1707		var sw = bounds.getSouthWest(),
1708		    ne = bounds.getNorthEast(),
1709		    newSw = new LatLng(sw.lat - latShift, sw.lng - lngShift),
1710		    newNe = new LatLng(ne.lat - latShift, ne.lng - lngShift);
1711
1712		return new LatLngBounds(newSw, newNe);
1713	}
1714};
1715
1716/*
1717 * @namespace CRS
1718 * @crs L.CRS.Earth
1719 *
1720 * Serves as the base for CRS that are global such that they cover the earth.
1721 * Can only be used as the base for other CRS and cannot be used directly,
1722 * since it does not have a `code`, `projection` or `transformation`. `distance()` returns
1723 * meters.
1724 */
1725
1726var Earth = extend({}, CRS, {
1727	wrapLng: [-180, 180],
1728
1729	// Mean Earth Radius, as recommended for use by
1730	// the International Union of Geodesy and Geophysics,
1731	// see http://rosettacode.org/wiki/Haversine_formula
1732	R: 6371000,
1733
1734	// distance between two geographical points using spherical law of cosines approximation
1735	distance: function (latlng1, latlng2) {
1736		var rad = Math.PI / 180,
1737		    lat1 = latlng1.lat * rad,
1738		    lat2 = latlng2.lat * rad,
1739		    sinDLat = Math.sin((latlng2.lat - latlng1.lat) * rad / 2),
1740		    sinDLon = Math.sin((latlng2.lng - latlng1.lng) * rad / 2),
1741		    a = sinDLat * sinDLat + Math.cos(lat1) * Math.cos(lat2) * sinDLon * sinDLon,
1742		    c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
1743		return this.R * c;
1744	}
1745});
1746
1747/*
1748 * @namespace Projection
1749 * @projection L.Projection.SphericalMercator
1750 *
1751 * Spherical Mercator projection — the most common projection for online maps,
1752 * used by almost all free and commercial tile providers. Assumes that Earth is
1753 * a sphere. Used by the `EPSG:3857` CRS.
1754 */
1755
1756var SphericalMercator = {
1757
1758	R: 6378137,
1759	MAX_LATITUDE: 85.0511287798,
1760
1761	project: function (latlng) {
1762		var d = Math.PI / 180,
1763		    max = this.MAX_LATITUDE,
1764		    lat = Math.max(Math.min(max, latlng.lat), -max),
1765		    sin = Math.sin(lat * d);
1766
1767		return new Point(
1768			this.R * latlng.lng * d,
1769			this.R * Math.log((1 + sin) / (1 - sin)) / 2);
1770	},
1771
1772	unproject: function (point) {
1773		var d = 180 / Math.PI;
1774
1775		return new LatLng(
1776			(2 * Math.atan(Math.exp(point.y / this.R)) - (Math.PI / 2)) * d,
1777			point.x * d / this.R);
1778	},
1779
1780	bounds: (function () {
1781		var d = 6378137 * Math.PI;
1782		return new Bounds([-d, -d], [d, d]);
1783	})()
1784};
1785
1786/*
1787 * @class Transformation
1788 * @aka L.Transformation
1789 *
1790 * Represents an affine transformation: a set of coefficients `a`, `b`, `c`, `d`
1791 * for transforming a point of a form `(x, y)` into `(a*x + b, c*y + d)` and doing
1792 * the reverse. Used by Leaflet in its projections code.
1793 *
1794 * @example
1795 *
1796 * ```js
1797 * var transformation = L.transformation(2, 5, -1, 10),
1798 * 	p = L.point(1, 2),
1799 * 	p2 = transformation.transform(p), //  L.point(7, 8)
1800 * 	p3 = transformation.untransform(p2); //  L.point(1, 2)
1801 * ```
1802 */
1803
1804
1805// factory new L.Transformation(a: Number, b: Number, c: Number, d: Number)
1806// Creates a `Transformation` object with the given coefficients.
1807function Transformation(a, b, c, d) {
1808	if (isArray(a)) {
1809		// use array properties
1810		this._a = a[0];
1811		this._b = a[1];
1812		this._c = a[2];
1813		this._d = a[3];
1814		return;
1815	}
1816	this._a = a;
1817	this._b = b;
1818	this._c = c;
1819	this._d = d;
1820}
1821
1822Transformation.prototype = {
1823	// @method transform(point: Point, scale?: Number): Point
1824	// Returns a transformed point, optionally multiplied by the given scale.
1825	// Only accepts actual `L.Point` instances, not arrays.
1826	transform: function (point, scale) { // (Point, Number) -> Point
1827		return this._transform(point.clone(), scale);
1828	},
1829
1830	// destructive transform (faster)
1831	_transform: function (point, scale) {
1832		scale = scale || 1;
1833		point.x = scale * (this._a * point.x + this._b);
1834		point.y = scale * (this._c * point.y + this._d);
1835		return point;
1836	},
1837
1838	// @method untransform(point: Point, scale?: Number): Point
1839	// Returns the reverse transformation of the given point, optionally divided
1840	// by the given scale. Only accepts actual `L.Point` instances, not arrays.
1841	untransform: function (point, scale) {
1842		scale = scale || 1;
1843		return new Point(
1844		        (point.x / scale - this._b) / this._a,
1845		        (point.y / scale - this._d) / this._c);
1846	}
1847};
1848
1849// factory L.transformation(a: Number, b: Number, c: Number, d: Number)
1850
1851// @factory L.transformation(a: Number, b: Number, c: Number, d: Number)
1852// Instantiates a Transformation object with the given coefficients.
1853
1854// @alternative
1855// @factory L.transformation(coefficients: Array): Transformation
1856// Expects an coefficients array of the form
1857// `[a: Number, b: Number, c: Number, d: Number]`.
1858
1859function toTransformation(a, b, c, d) {
1860	return new Transformation(a, b, c, d);
1861}
1862
1863/*
1864 * @namespace CRS
1865 * @crs L.CRS.EPSG3857
1866 *
1867 * The most common CRS for online maps, used by almost all free and commercial
1868 * tile providers. Uses Spherical Mercator projection. Set in by default in
1869 * Map's `crs` option.
1870 */
1871
1872var EPSG3857 = extend({}, Earth, {
1873	code: 'EPSG:3857',
1874	projection: SphericalMercator,
1875
1876	transformation: (function () {
1877		var scale = 0.5 / (Math.PI * SphericalMercator.R);
1878		return toTransformation(scale, 0.5, -scale, 0.5);
1879	}())
1880});
1881
1882var EPSG900913 = extend({}, EPSG3857, {
1883	code: 'EPSG:900913'
1884});
1885
1886// @namespace SVG; @section
1887// There are several static functions which can be called without instantiating L.SVG:
1888
1889// @function create(name: String): SVGElement
1890// Returns a instance of [SVGElement](https://developer.mozilla.org/docs/Web/API/SVGElement),
1891// corresponding to the class name passed. For example, using 'line' will return
1892// an instance of [SVGLineElement](https://developer.mozilla.org/docs/Web/API/SVGLineElement).
1893function svgCreate(name) {
1894	return document.createElementNS('http://www.w3.org/2000/svg', name);
1895}
1896
1897// @function pointsToPath(rings: Point[], closed: Boolean): String
1898// Generates a SVG path string for multiple rings, with each ring turning
1899// into "M..L..L.." instructions
1900function pointsToPath(rings, closed) {
1901	var str = '',
1902	i, j, len, len2, points, p;
1903
1904	for (i = 0, len = rings.length; i < len; i++) {
1905		points = rings[i];
1906
1907		for (j = 0, len2 = points.length; j < len2; j++) {
1908			p = points[j];
1909			str += (j ? 'L' : 'M') + p.x + ' ' + p.y;
1910		}
1911
1912		// closes the ring for polygons; "x" is VML syntax
1913		str += closed ? (svg ? 'z' : 'x') : '';
1914	}
1915
1916	// SVG complains about empty path strings
1917	return str || 'M0 0';
1918}
1919
1920/*
1921 * @namespace Browser
1922 * @aka L.Browser
1923 *
1924 * A namespace with static properties for browser/feature detection used by Leaflet internally.
1925 *
1926 * @example
1927 *
1928 * ```js
1929 * if (L.Browser.ielt9) {
1930 *   alert('Upgrade your browser, dude!');
1931 * }
1932 * ```
1933 */
1934
1935var style$1 = document.documentElement.style;
1936
1937// @property ie: Boolean; `true` for all Internet Explorer versions (not Edge).
1938var ie = 'ActiveXObject' in window;
1939
1940// @property ielt9: Boolean; `true` for Internet Explorer versions less than 9.
1941var ielt9 = ie && !document.addEventListener;
1942
1943// @property edge: Boolean; `true` for the Edge web browser.
1944var edge = 'msLaunchUri' in navigator && !('documentMode' in document);
1945
1946// @property webkit: Boolean;
1947// `true` for webkit-based browsers like Chrome and Safari (including mobile versions).
1948var webkit = userAgentContains('webkit');
1949
1950// @property android: Boolean
1951// `true` for any browser running on an Android platform.
1952var android = userAgentContains('android');
1953
1954// @property android23: Boolean; `true` for browsers running on Android 2 or Android 3.
1955var android23 = userAgentContains('android 2') || userAgentContains('android 3');
1956
1957/* See https://stackoverflow.com/a/17961266 for details on detecting stock Android */
1958var webkitVer = parseInt(/WebKit\/([0-9]+)|$/.exec(navigator.userAgent)[1], 10); // also matches AppleWebKit
1959// @property androidStock: Boolean; `true` for the Android stock browser (i.e. not Chrome)
1960var androidStock = android && userAgentContains('Google') && webkitVer < 537 && !('AudioNode' in window);
1961
1962// @property opera: Boolean; `true` for the Opera browser
1963var opera = !!window.opera;
1964
1965// @property chrome: Boolean; `true` for the Chrome browser.
1966var chrome = userAgentContains('chrome');
1967
1968// @property gecko: Boolean; `true` for gecko-based browsers like Firefox.
1969var gecko = userAgentContains('gecko') && !webkit && !opera && !ie;
1970
1971// @property safari: Boolean; `true` for the Safari browser.
1972var safari = !chrome && userAgentContains('safari');
1973
1974var phantom = userAgentContains('phantom');
1975
1976// @property opera12: Boolean
1977// `true` for the Opera browser supporting CSS transforms (version 12 or later).
1978var opera12 = 'OTransition' in style$1;
1979
1980// @property win: Boolean; `true` when the browser is running in a Windows platform
1981var win = navigator.platform.indexOf('Win') === 0;
1982
1983// @property ie3d: Boolean;
1983 `true` for all Internet Explorer versions supporting CSS transforms.
1984var ie3d = ie && ('transition' in style$1);
1985
1986// @property webkit3d: Boolean; `true` for webkit-based browsers supporting CSS transforms.
1987var webkit3d = ('WebKitCSSMatrix' in window) && ('m11' in new window.WebKitCSSMatrix()) && !android23;
1988
1989// @property gecko3d: Boolean; `true` for gecko-based browsers supporting CSS transforms.
1990var gecko3d = 'MozPerspective' in style$1;
1991
1992// @property any3d: Boolean
1993// `true` for all browsers supporting CSS transforms.
1994var any3d = !window.L_DISABLE_3D && (ie3d || webkit3d || gecko3d) && !opera12 && !phantom;
1995
1996// @property mobile: Boolean; `true` for all browsers running in a mobile device.
1997var mobile = typeof orientation !== 'undefined' || userAgentContains('mobile');
1998
1999// @property mobileWebkit: Boolean; `true` for all webkit-based browsers in a mobile device.
2000var mobileWebkit = mobile && webkit;
2001
2002// @property mobileWebkit3d: Boolean
2003// `true` for all webkit-based browsers in a mobile device supporting CSS transforms.
2004var mobileWebkit3d = mobile && webkit3d;
2005
2006// @property msPointer: Boolean
2007// `true` for browsers implementing the Microsoft touch events model (notably IE10).
2008var msPointer = !window.PointerEvent && window.MSPointerEvent;
2009
2010// @property pointer: Boolean
2011// `true` for all browsers supporting [pointer events](https://msdn.microsoft.com/en-us/library/dn433244%28v=vs.85%29.aspx).
2012var pointer = !!(window.PointerEvent || msPointer);
2013
2014// @property touch: Boolean
2015// `true` for all browsers supporting [touch events](https://developer.mozilla.org/docs/Web/API/Touch_events).
2016// This does not necessarily mean that the browser is running in a computer with
2017// a touchscreen, it only means that the browser is capable of understanding
2018// touch events.
2019var touch = !window.L_NO_TOUCH && (pointer || 'ontouchstart' in window ||
2020		(window.DocumentTouch && document instanceof window.DocumentTouch));
2021
2022// @property mobileOpera: Boolean; `true` for the Opera browser in a mobile device.
2023var mobileOpera = mobile && opera;
2024
2025// @property mobileGecko: Boolean
2026// `true` for gecko-based browsers running in a mobile device.
2027var mobileGecko = mobile && gecko;
2028
2029// @property retina: Boolean
2030// `true` for browsers on a high-resolution "retina" screen or on any screen when browser's display zoom is more than 100%.
2031var retina = (window.devicePixelRatio || (window.screen.deviceXDPI / window.screen.logicalXDPI)) > 1;
2032
2033
2034// @property canvas: Boolean
2035// `true` when the browser supports [`<canvas>`](https://developer.mozilla.org/docs/Web/API/Canvas_API).
2036var canvas = (function () {
2037	return !!document.createElement('canvas').getContext;
2038}());
2039
2040// @property svg: Boolean
2041// `true` when the browser supports [SVG](https://developer.mozilla.org/docs/Web/SVG).
2042var svg = !!(document.createElementNS && svgCreate('svg').createSVGRect);
2043
2044// @property vml: Boolean
2045// `true` if the browser supports [VML](https://en.wikipedia.org/wiki/Vector_Markup_Language).
2046var vml = !svg && (function () {
2047	try {
2048		var div = document.createElement('div');
2049		div.innerHTML = '<v:shape adj="1"/>';
2050
2051		var shape = div.firstChild;
2052		shape.style.behavior = 'url(#default#VML)';
2053
2054		return shape && (typeof shape.adj === 'object');
2055
2056	} catch (e) {
2057		return false;
2058	}
2059}());
2060
2061
2062function userAgentContains(str) {
2063	return navigator.userAgent.toLowerCase().indexOf(str) >= 0;
2064}
2065
2066
2067var Browser = (Object.freeze || Object)({
2068	ie: ie,
2069	ielt9: ielt9,
2070	edge: edge,
2071	webkit: webkit,
2072	android: android,
2073	android23: android23,
2074	androidStock: androidStock,
2075	opera: opera,
2076	chrome: chrome,
2077	gecko: gecko,
2078	safari: safari,
2079	phantom: phantom,
2080	opera12: opera12,
2081	win: win,
2082	ie3d: ie3d,
2083	webkit3d: webkit3d,
2084	gecko3d: gecko3d,
2085	any3d: any3d,
2086	mobile: mobile,
2087	mobileWebkit: mobileWebkit,
2088	mobileWebkit3d: mobileWebkit3d,
2089	msPointer: msPointer,
2090	pointer: pointer,
2091	touch: touch,
2092	mobileOpera: mobileOpera,
2093	mobileGecko: mobileGecko,
2094	retina: retina,
2095	canvas: canvas,
2096	svg: svg,
2097	vml: vml
2098});
2099
2100/*
2101 * Extends L.DomEvent to provide touch support for Internet Explorer and Windows-based devices.
2102 */
2103
2104
2105var POINTER_DOWN =   msPointer ? 'MSPointerDown'   : 'pointerdown';
2106var POINTER_MOVE =   msPointer ? 'MSPointerMove'   : 'pointermove';
2107var POINTER_UP =     msPointer ? 'MSPointerUp'     : 'pointerup';
2108var POINTER_CANCEL = msPointer ? 'MSPointerCancel' : 'pointercancel';
2109var TAG_WHITE_LIST = ['INPUT', 'SELECT', 'OPTION'];
2110
2111var _pointers = {};
2112var _pointerDocListener = false;
2113
2114// DomEvent.DoubleTap needs to know about this
2115var _pointersCount = 0;
2116
2117// Provides a touch events wrapper for (ms)pointer events.
2118// ref http://www.w3.org/TR/pointerevents/ https://www.w3.org/Bugs/Public/show_bug.cgi?id=22890
2119
2120function addPointerListener(obj, type, handler, id) {
2121	if (type === 'touchstart') {
2122		_addPointerStart(obj, handler, id);
2123
2124	} else if (type === 'touchmove') {
2125		_addPointerMove(obj, handler, id);
2126
2127	} else if (type === 'touchend') {
2128		_addPointerEnd(obj, handler, id);
2129	}
2130
2131	return this;
2132}
2133
2134function removePointerListener(obj, type, id) {
2135	var handler = obj['_leaflet_' + type + id];
2136
2137	if (type === 'touchstart') {
2138		obj.removeEventListener(POINTER_DOWN, handler, false);
2139
2140	} else if (type === 'touchmove') {
2141		obj.removeEventListener(POINTER_MOVE, handler, false);
2142
2143	} else if (type === 'touchend') {
2144		obj.removeEventListener(POINTER_UP, handler, false);
2145		obj.removeEventListener(POINTER_CANCEL, handler, false);
2146	}
2147
2148	return this;
2149}
2150
2151function _addPointerStart(obj, handler, id) {
2152	var onDown = bind(function (e) {
2153		if (e.pointerType !== 'mouse' && e.MSPOINTER_TYPE_MOUSE && e.pointerType !== e.MSPOINTER_TYPE_MOUSE) {
2154			// In IE11, some touch events needs to fire for form controls, or
2155			// the controls will stop working. We keep a whitelist of tag names that
2156			// need these events. For other target tags, we prevent default on the event.
2157			if (TAG_WHITE_LIST.indexOf(e.target.tagName) < 0) {
2158				preventDefault(e);
2159			} else {
2160				return;
2161			}
2162		}
2163
2164		_handlePointer(e, handler);
2165	});
2166
2167	obj['_leaflet_touchstart' + id] = onDown;
2168	obj.addEventListener(POINTER_DOWN, onDown, false);
2169
2170	// need to keep track of what pointers and how many are active to provide e.touches emulation
2171	if (!_pointerDocListener) {
2172		// we listen documentElement as any drags that end by moving the touch off the screen get fired there
2173		document.documentElement.addEventListener(POINTER_DOWN, _globalPointerDown, true);
2174		document.documentElement.addEventListener(POINTER_MOVE, _globalPointerMove, true);
2175		document.documentElement.addEventListener(POINTER_UP, _globalPointerUp, true);
2176		document.documentElement.addEventListener(POINTER_CANCEL, _globalPointerUp, true);
2177
2178		_pointerDocListener = true;
2179	}
2180}
2181
2182function _globalPointerDown(e) {
2183	_pointers[e.pointerId] = e;
2184	_pointersCount++;
2185}
2186
2187function _globalPointerMove(e) {
2188	if (_pointers[e.pointerId]) {
2189		_pointers[e.pointerId] = e;
2190	}
2191}
2192
2193function _globalPointerUp(e) {
2194	delete _pointers[e.pointerId];
2195	_pointersCount--;
2196}
2197
2198function _handlePointer(e, handler) {
2199	e.touches = [];
2200	for (var i in _pointers) {
2201		e.touches.push(_pointers[i]);
2202	}
2203	e.changedTouches = [e];
2204
2205	handler(e);
2206}
2207
2208function _addPointerMove(obj, handler, id) {
2209	var onMove = function (e) {
2210		// don't fire touch moves when mouse isn't down
2211		if ((e.pointerType === e.MSPOINTER_TYPE_MOUSE || e.pointerType === 'mouse') && e.buttons === 0) { return; }
2212
2213		_handlePointer(e, handler);
2214	};
2215
2216	obj['_leaflet_touchmove' + id] = onMove;
2217	obj.addEventListener(POINTER_MOVE, onMove, false);
2218}
2219
2220function _addPointerEnd(obj, handler, id) {
2221	var onUp = function (e) {
2222		_handlePointer(e, handler);
2223	};
2224
2225	obj['_leaflet_touchend' + id] = onUp;
2226	obj.addEventListener(POINTER_UP, onUp, false);
2227	obj.addEventListener(POINTER_CANCEL, onUp, false);
2228}
2229
2230/*
2231 * Extends the event handling code with double tap support for mobile browsers.
2232 */
2233
2234var _touchstart = msPointer ? 'MSPointerDown' : pointer ? 'pointerdown' : 'touchstart';
2235var _touchend = msPointer ? 'MSPointerUp' : pointer ? 'pointerup' : 'touchend';
2236var _pre = '_leaflet_';
2237
2238// inspired by Zepto touch code by Thomas Fuchs
2239function addDoubleTapListener(obj, handler, id) {
2240	var last, touch$$1,
2241	    doubleTap = false,
2242	    delay = 250;
2243
2244	function onTouchStart(e) {
2245		var count;
2246
2247		if (pointer) {
2248			if ((!edge) || e.pointerType === 'mouse') { return; }
2249			count = _pointersCount;
2250		} else {
2251			count = e.touches.length;
2252		}
2253
2254		if (count > 1) { return; }
2255
2256		var now = Date.now(),
2257		    delta = now - (last || now);
2258
2259		touch$$1 = e.touches ? e.touches[0] : e;
2260		doubleTap = (delta > 0 && delta <= delay);
2261		last = now;
2262	}
2263
2264	function onTouchEnd(e) {
2265		if (doubleTap && !touch$$1.cancelBubble) {
2266			if (pointer) {
2267				if ((!edge) || e.pointerType === 'mouse') { return; }
2268				// work around .type being readonly with MSPointer* events
2269				var newTouch = {},
2270				    prop, i;
2271
2272				for (i in touch$$1) {
2273					prop = touch$$1[i];
2274					newTouch[i] = prop && prop.bind ? prop.bind(touch$$1) : prop;
2275				}
2276				touch$$1 = newTouch;
2277			}
2278			touch$$1.type = 'dblclick';
2279			handler(touch$$1);
2280			last = null;
2281		}
2282	}
2283
2284	obj[_pre + _touchstart + id] = onTouchStart;
2285	obj[_pre + _touchend + id] = onTouchEnd;
2286	obj[_pre + 'dblclick' + id] = handler;
2287
2288	obj.addEventListener(_touchstart, onTouchStart, false);
2289	obj.addEventListener(_touchend, onTouchEnd, false);
2290
2291	// On some platforms (notably, chrome<55 on win10 + touchscreen + mouse),
2292	// the browser doesn't fire touchend/pointerup events but does fire
2293	// native dblclicks. See #4127.
2294	// Edge 14 also fires native dblclicks, but only for pointerType mouse, see #5180.
2295	obj.addEventListener('dblclick', handler, false);
2296
2297	return this;
2298}
2299
2300function removeDoubleTapListener(obj, id) {
2301	var touchstart = obj[_pre + _touchstart + id],
2302	    touchend = obj[_pre + _touchend + id],
2303	    dblclick = obj[_pre + 'dblclick' + id];
2304
2305	obj.removeEventListener(_touchstart, touchstart, false);
2306	obj.removeEventListener(_touchend, touchend, false);
2307	if (!edge) {
2308		obj.removeEventListener('dblclick', dblclick, false);
2309	}
2310
2311	return this;
2312}
2313
2314/*
2315 * @namespace DomUtil
2316 *
2317 * Utility functions to work with the [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model)
2318 * tree, used by Leaflet internally.
2319 *
2320 * Most functions expecting or returning a `HTMLElement` also work for
2321 * SVG elements. The only difference is that classes refer to CSS classes
2322 * in HTML and SVG classes in SVG.
2323 */
2324
2325
2326// @property TRANSFORM: String
2327// Vendor-prefixed transform style name (e.g. `'webkitTransform'` for WebKit).
2328var TRANSFORM = testProp(
2329	['transform', 'webkitTransform', 'OTransform', 'MozTransform', 'msTransform']);
2330
2331// webkitTransition comes first because some browser versions that drop vendor prefix don't do
2332// the same for the transitionend event, in particular the Android 4.1 stock browser
2333
2334// @property TRANSITION: String
2335// Vendor-prefixed transition style name.
2336var TRANSITION = testProp(
2337	['webkitTransition', 'transition', 'OTransition', 'MozTransition', 'msTransition']);
2338
2339// @property TRANSITION_END: String
2340// Vendor-prefixed transitionend event name.
2341var TRANSITION_END =
2342	TRANSITION === 'webkitTransition' || TRANSITION === 'OTransition' ? TRANSITION + 'End' : 'transitionend';
2343
2344
2345// @function get(id: String|HTMLElement): HTMLElement
2346// Returns an element given its DOM id, or returns the element itself
2347// if it was passed directly.
2348function get(id) {
2349	return typeof id === 'string' ? document.getElementById(id) : id;
2350}
2351
2352// @function getStyle(el: HTMLElement, styleAttrib: String): String
2353// Returns the value for a certain style attribute on an element,
2354// including computed values or values set through CSS.
2355function getStyle(el, style) {
2356	var value = el.style[style] || (el.currentStyle && el.currentStyle[style]);
2357
2358	if ((!value || value === 'auto') && document.defaultView) {
2359		var css = document.defaultView.getComputedStyle(el, null);
2360		value = css ? css[style] : null;
2361	}
2362	return value === 'auto' ? null : value;
2363}
2364
2365// @function create(tagName: String, className?: String, container?: HTMLElement): HTMLElement
2366// Creates an HTML element with `tagName`, sets its class to `className`, and optionally appends it to `container` element.
2367function create$1(tagName, className, container) {
2368	var el = document.createElement(tagName);
2369	el.className = className || '';
2370
2371	if (container) {
2372		container.appendChild(el);
2373	}
2374	return el;
2375}
2376
2377// @function remove(el: HTMLElement)
2378// Removes `el` from its parent element
2379function remove(el) {
2380	var parent = el.parentNode;
2381	if (parent) {
2382		parent.removeChild(el);
2383	}
2384}
2385
2386// @function empty(el: HTMLElement)
2387// Removes all of `el`'s children elements from `el`
2388function empty(el) {
2389	while (el.firstChild) {
2390		el.removeChild(el.firstChild);
2391	}
2392}
2393
2394// @function toFront(el: HTMLElement)
vendor: 9,278 bytes, lines 2395-2691
2395// Makes `el` the last child of its parent, so it renders in front of the other children.
2396function toFront(el) {
2397	var parent = el.parentNode;
2398	if (parent.lastChild !== el) {
2399		parent.appendChild(el);
2400	}
2401}
2402
2403// @function toBack(el: HTMLElement)
2404// Makes `el` the first child of its parent, so it renders behind the other children.
2405function toBack(el) {
2406	var parent = el.parentNode;
2407	if (parent.firstChild !== el) {
2408		parent.insertBefore(el, parent.firstChild);
2409	}
2410}
2411
2412// @function hasClass(el: HTMLElement, name: String): Boolean
2413// Returns `true` if the element's class attribute contains `name`.
2414function hasClass(el, name) {
2415	if (el.classList !== undefined) {
2416		return el.classList.contains(name);
2417	}
2418	var className = getClass(el);
2419	return className.length > 0 && new RegExp('(^|\\s)' + name + '(\\s|$)').test(className);
2420}
2421
2422// @function addClass(el: HTMLElement, name: String)
2423// Adds `name` to the element's class attribute.
2424function addClass(el, name) {
2425	if (el.classList !== undefined) {
2426		var classes = splitWords(name);
2427		for (var i = 0, len = classes.length; i < len; i++) {
2428			el.classList.add(classes[i]);
2429		}
2430	} else if (!hasClass(el, name)) {
2431		var className = getClass(el);
2432		setClass(el, (className ? className + ' ' : '') + name);
2433	}
2434}
2435
2436// @function removeClass(el: HTMLElement, name: String)
2437// Removes `name` from the element's class attribute.
2438function removeClass(el, name) {
2439	if (el.classList !== undefined) {
2440		el.classList.remove(name);
2441	} else {
2442		setClass(el, trim((' ' + getClass(el) + ' ').replace(' ' + name + ' ', ' ')));
2443	}
2444}
2445
2446// @function setClass(el: HTMLElement, name: String)
2447// Sets the element's class.
2448function setClass(el, name) {
2449	if (el.className.baseVal === undefined) {
2450		el.className = name;
2451	} else {
2452		// in case of SVG element
2453		el.className.baseVal = name;
2454	}
2455}
2456
2457// @function getClass(el: HTMLElement): String
2458// Returns the element's class.
2459function getClass(el) {
2460	return el.className.baseVal === undefined ? el.className : el.className.baseVal;
2461}
2462
2463// @function setOpacity(el: HTMLElement, opacity: Number)
2464// Set the opacity of an element (including old IE support).
2465// `opacity` must be a number from `0` to `1`.
2466function setOpacity(el, value) {
2467	if ('opacity' in el.style) {
2468		el.style.opacity = value;
2469	} else if ('filter' in el.style) {
2470		_setOpacityIE(el, value);
2471	}
2472}
2473
2474function _setOpacityIE(el, value) {
2475	var filter = false,
2476	    filterName = 'DXImageTransform.Microsoft.Alpha';
2477
2478	// filters collection throws an error if we try to retrieve a filter that doesn't exist
2479	try {
2480		filter = el.filters.item(filterName);
2481	} catch (e) {
2482		// don't set opacity to 1 if we haven't already set an opacity,
2483		// it isn't needed and breaks transparent pngs.
2484		if (value === 1) { return; }
2485	}
2486
2487	value = Math.round(value * 100);
2488
2489	if (filter) {
2490		filter.Enabled = (value !== 100);
2491		filter.Opacity = value;
2492	} else {
2493		el.style.filter += ' progid:' + filterName + '(opacity=' + value + ')';
2494	}
2495}
2496
2497// @function testProp(props: String[]): String|false
2498// Goes through the array of style names and returns the first name
2499// that is a valid style name for an element. If no such name is found,
2500// it returns false. Useful for vendor-prefixed styles like `transform`.
2501function testProp(props) {
2502	var style = document.documentElement.style;
2503
2504	for (var i = 0; i < props.length; i++) {
2505		if (props[i] in style) {
2506			return props[i];
2507		}
2508	}
2509	return false;
2510}
2511
2512// @function setTransform(el: HTMLElement, offset: Point, scale?: Number)
2513// Resets the 3D CSS transform of `el` so it is translated by `offset` pixels
2514// and optionally scaled by `scale`. Does not have an effect if the
2515// browser doesn't support 3D CSS transforms.
2516function setTransform(el, offset, scale) {
2517	var pos = offset || new Point(0, 0);
2518
2519	el.style[TRANSFORM] =
2520		(ie3d ?
2521			'translate(' + pos.x + 'px,' + pos.y + 'px)' :
2522			'translate3d(' + pos.x + 'px,' + pos.y + 'px,0)') +
2523		(scale ? ' scale(' + scale + ')' : '');
2524}
2525
2526// @function setPosition(el: HTMLElement, position: Point)
2527// Sets the position of `el` to coordinates specified by `position`,
2528// using CSS translate or top/left positioning depending on the browser
2529// (used by Leaflet internally to position its layers).
2530function setPosition(el, point) {
2531
2532	/*eslint-disable */
2533	el._leaflet_pos = point;
2534	/* eslint-enable */
2535
2536	if (any3d) {
2537		setTransform(el, point);
2538	} else {
2539		el.style.left = point.x + 'px';
2540		el.style.top = point.y + 'px';
2541	}
2542}
2543
2544// @function getPosition(el: HTMLElement): Point
2545// Returns the coordinates of an element previously positioned with setPosition.
2546function getPosition(el) {
2547	// this method is only used for elements previously positioned using setPosition,
2548	// so it's safe to cache the position for performance
2549
2550	return el._leaflet_pos || new Point(0, 0);
2551}
2552
2553// @function disableTextSelection()
2554// Prevents the user from generating `selectstart` DOM events, usually generated
2555// when the user drags the mouse through a page with text. Used internally
2556// by Leaflet to override the behaviour of any click-and-drag interaction on
2557// the map. Affects drag interactions on the whole document.
2558
2559// @function enableTextSelection()
2560// Cancels the effects of a previous [`L.DomUtil.disableTextSelection`](#domutil-disabletextselection).
2561var disableTextSelection;
2562var enableTextSelection;
2563var _userSelect;
2564if ('onselectstart' in document) {
2565	disableTextSelection = function () {
2566		on(window, 'selectstart', preventDefault);
2567	};
2568	enableTextSelection = function () {
2569		off(window, 'selectstart', preventDefault);
2570	};
2571} else {
2572	var userSelectProperty = testProp(
2573		['userSelect', 'WebkitUserSelect', 'OUserSelect', 'MozUserSelect', 'msUserSelect']);
2574
2575	disableTextSelection = function () {
2576		if (userSelectProperty) {
2577			var style = document.documentElement.style;
2578			_userSelect = style[userSelectProperty];
2579			style[userSelectProperty] = 'none';
2580		}
2581	};
2582	enableTextSelection = function () {
2583		if (userSelectProperty) {
2584			document.documentElement.style[userSelectProperty] = _userSelect;
2585			_userSelect = undefined;
2586		}
2587	};
2588}
2589
2590// @function disableImageDrag()
2591// As [`L.DomUtil.disableTextSelection`](#domutil-disabletextselection), but
2592// for `dragstart` DOM events, usually generated when the user drags an image.
2593function disableImageDrag() {
2594	on(window, 'dragstart', preventDefault);
2595}
2596
2597// @function enableImageDrag()
2598// Cancels the effects of a previous [`L.DomUtil.disableImageDrag`](#domutil-disabletextselection).
2599function enableImageDrag() {
2600	off(window, 'dragstart', preventDefault);
2601}
2602
2603var _outlineElement;
2604var _outlineStyle;
2605// @function preventOutline(el: HTMLElement)
2606// Makes the [outline](https://developer.mozilla.org/docs/Web/CSS/outline)
2607// of the element `el` invisible. Used internally by Leaflet to prevent
2608// focusable elements from displaying an outline when the user performs a
2609// drag interaction on them.
2610function preventOutline(element) {
2611	while (element.tabIndex === -1) {
2612		element = element.parentNode;
2613	}
2614	if (!element.style) { return; }
2615	restoreOutline();
2616	_outlineElement = element;
2617	_outlineStyle = element.style.outline;
2618	element.style.outline = 'none';
2619	on(window, 'keydown', restoreOutline);
2620}
2621
2622// @function restoreOutline()
2623// Cancels the effects of a previous [`L.DomUtil.preventOutline`]().
2624function restoreOutline() {
2625	if (!_outlineElement) { return; }
2626	_outlineElement.style.outline = _outlineStyle;
2627	_outlineElement = undefined;
2628	_outlineStyle = undefined;
2629	off(window, 'keydown', restoreOutline);
2630}
2631
2632// @function getSizedParentNode(el: HTMLElement): HTMLElement
2633// Finds the closest parent node which size (width and height) is not null.
2634function getSizedParentNode(element) {
2635	do {
2636		element = element.parentNode;
2637	} while ((!element.offsetWidth || !element.offsetHeight) && element !== document.body);
2638	return element;
2639}
2640
2641// @function getScale(el: HTMLElement): Object
2642// Computes the CSS scale currently applied on the element.
2643// Returns an object with `x` and `y` members as horizontal and vertical scales respectively,
2644// and `boundingClientRect` as the result of [`getBoundingClientRect()`](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect).
2645function getScale(element) {
2646	var rect = element.getBoundingClientRect(); // Read-only in old browsers.
2647
2648	return {
2649		x: rect.width / element.offsetWidth || 1,
2650		y: rect.height / element.offsetHeight || 1,
2651		boundingClientRect: rect
2652	};
2653}
2654
2655
2656var DomUtil = (Object.freeze || Object)({
2657	TRANSFORM: TRANSFORM,
2658	TRANSITION: TRANSITION,
2659	TRANSITION_END: TRANSITION_END,
2660	get: get,
2661	getStyle: getStyle,
2662	create: create$1,
2663	remove: remove,
2664	empty: empty,
2665	toFront: toFront,
2666	toBack: toBack,
2667	hasClass: hasClass,
2668	addClass: addClass,
2669	removeClass: removeClass,
2670	setClass: setClass,
2671	getClass: getClass,
2672	setOpacity: setOpacity,
2673	testProp: testProp,
2674	setTransform: setTransform,
2675	setPosition: setPosition,
2676	getPosition: getPosition,
2677	disableTextSelection: disableTextSelection,
2678	enableTextSelection: enableTextSelection,
2679	disableImageDrag: disableImageDrag,
2680	enableImageDrag: enableImageDrag,
2681	preventOutline: preventOutline,
2682	restoreOutline: restoreOutline,
2683	getSizedParentNode: getSizedParentNode,
2684	getScale: getScale
2685});
2686
2687/*
2688 * @namespace DomEvent
2689 * Utility functions to work with the [DOM events](https://developer.mozilla.org/docs/Web/API/Event), used by Leaflet internally.
2690 */
2691
2692// Inspired by John Resig, Dean Edwards and YUI addEvent implementations.
2693
2694// @function on(el: HTMLElement, types: String, fn: Function, context?: Object): this
2695// Adds a listener function (`fn`) to a particular DOM event type of the
2696// element `el`. You can optionally specify the context of the listener
2697// (object the `this` keyword will point to). You can also pass several
2698// space-separated types (e.g. `'click dblclick'`).
2699
2700// @alternative
2701// @function on(el: HTMLElement, eventMap: Object, context?: Object): this
2702// Adds a set of type/listener pairs, e.g. `{click: onClick, mousemove: onMouseMove}`
2703function on(obj, types, fn, context) {
2704
2705	if (typeof types === 'object') {
2706		for (var type in types) {
2707			addOne(obj, type, types[type], fn);
2708		}
2709	} else {
2710		types = splitWords(types);
2711
2712		for (var i = 0, len = types.length; i < len; i++) {
2713			addOne(obj, types[i], fn, context);
2714		}
2715	}
2716
2717	return this;
2718}
2719
2720var eventsKey = '_leaflet_events';
2721
2722// @function off(el: HTMLElement, types: String, fn: Function, context?: Object): this
2723// Removes a previously added listener function.
2724// Note that if you passed a custom context to on, you must pass the same
2725// context to `off` in order to remove the listener.
2726
2727// @alternative
2728// @function off(el: HTMLElement, eventMap: Object, context?: Object): this
2729// Removes a set of type/listener pairs, e.g. `{click: onClick, mousemove: onMouseMove}`
2730function off(obj, types, fn, context) {
2731
2732	if (typeof types === 'object') {
2733		for (var type in types) {
2734			removeOne(obj, type, types[type], fn);
2735		}
2736	} else if (types) {
2737		types = splitWords(types);
2738
2739		for (var i = 0, len = types.length; i < len; i++) {
2740			removeOne(obj, types[i], fn, context);
2741		}
2742	} else {
2743		for (var j in obj[eventsKey]) {
2744			removeOne(obj, j, obj[eventsKey][j]);
2745		}
2746		delete obj[eventsKey];
2747	}
2748
2749	return this;
2750}
2751
2752function addOne(obj, type, fn, context) {
2753	var id = type + stamp(fn) + (context ? '_' + stamp(context) : '');
2754
2755	if (obj[eventsKey] && obj[eventsKey][id]) { return this; }
2756
2757	var handler = function (e) {
2758		return fn.call(context || obj, e || window.event);
2759	};
2760
2761	var originalHandler = handler;
2762
2763	if (pointer && type.indexOf('touch') === 0) {
2764		// Needs DomEvent.Pointer.js
2765		addPointerListener(obj, type, handler, id);
2766
2767	} else if (touch && (type === 'dblclick') && addDoubleTapListener &&
2768	           !(pointer && chrome)) {
2769		// Chrome >55 does not need the synthetic dblclicks from addDoubleTapListener
2770		// See #5180
2771		addDoubleTapListener(obj, handler, id);
2772
2773	} else if ('addEventListener' in obj) {
2774
2775		if (type === 'mousewheel') {
2776			obj.addEventListener('onwheel' in obj ? 'wheel' : 'mousewheel', handler, false);
2777
2778		} else if ((type === 'mouseenter') || (type === 'mouseleave')) {
2779			handler = function (e) {
2780				e = e || window.event;
2781				if (isExternalTarget(obj, e)) {
2782					originalHandler(e);
2783				}
2784			};
2785			obj.addEventListener(type === 'mouseenter' ? 'mouseover' : 'mouseout', handler, false);
2786
2787		} else {
2788			if (type === 'click' && android) {
2789				handler = function (e) {
2790					filterClick(e, originalHandler);
2791				};
2792			}
2793			obj.addEventListener(type, handler, false);
2794		}
2795
2796	} else if ('attachEvent' in obj) {
2797		obj.attachEvent('on' + type, handler);
2798	}
2799
2800	obj[eventsKey] = obj[eventsKey] || {};
2801	obj[eventsKey][id] = handler;
2802}
2803
2804function removeOne(obj, type, fn, context) {
2805
2806	var id = type + stamp(fn) + (context ? '_' + stamp(context) : ''),
2807	    handler = obj[eventsKey] && obj[eventsKey][id];
2808
2809	if (!handler) { return this; }
2810
2811	if (pointer && type.indexOf('touch') === 0) {
2812		removePointerListener(obj, type, id);
2813
2814	} else if (touch && (type === 'dblclick') && removeDoubleTapListener &&
2815	           !(pointer && chrome)) {
2816		removeDoubleTapListener(obj, id);
2817
2818	} else if ('removeEventListener' in obj) {
2819
2820		if (type === 'mousewheel') {
2821			obj.removeEventListener('onwheel' in obj ? 'wheel' : 'mousewheel', handler, false);
2822
2823		} else {
2824			obj.removeEventListener(
2825				type === 'mouseenter' ? 'mouseover' :
2826				type === 'mouseleave' ? 'mouseout' : type, handler, false);
2827		}
2828
2829	} else if ('detachEvent' in obj) {
2830		obj.detachEvent('on' + type, handler);
2831	}
2832
2833	obj[eventsKey][id] = null;
2834}
2835
2836// @function stopPropagation(ev: DOMEvent): this
2837// Stop the given event from propagation to parent elements. Used inside the listener functions:
2838// ```js
2839// L.DomEvent.on(div, 'click', function (ev) {
2840// 	L.DomEvent.stopPropagation(ev);
2841// });
2842// ```
2843function stopPropagation(e) {
2844
2845	if (e.stopPropagation) {
2846		e.stopPropagation();
2847	} else if (e.originalEvent) {  // In case of Leaflet event.
2848		e.originalEvent._stopped = true;
2849	} else {
2850		e.cancelBubble = true;
2851	}
2852	skipped(e);
2853
2854	return this;
2855}
2856
2857// @function disableScrollPropagation(el: HTMLElement): this
2858// Adds `stopPropagation` to the element's `'mousewheel'` events (plus browser variants).
2859function disableScrollPropagation(el) {
2860	addOne(el, 'mousewheel', stopPropagation);
2861	return this;
2862}
2863
2864// @function disableClickPropagation(el: HTMLElement): this
2865// Adds `stopPropagation` to the element's `'click'`, `'doubleclick'`,
2866// `'mousedown'` and `'touchstart'` events (plus browser variants).
2867function disableClickPropagation(el) {
2868	on(el, 'mousedown touchstart dblclick', stopPropagation);
2869	addOne(el, 'click', fakeStop);
2870	return this;
2871}
2872
2873// @function preventDefault(ev: DOMEvent): this
2874// Prevents the default action of the DOM Event `ev` from happening (such as
2875// following a link in the href of the a element, or doing a POST request
2876// with page reload when a `<form>` is submitted).
2877// Use it inside listener functions.
2878function preventDefault(e) {
2879	if (e.preventDefault) {
2880		e.preventDefault();
2881	} else {
2882		e.returnValue = false;
2883	}
2884	return this;
2885}
2886
2887// @function stop(ev: DOMEvent): this
2888// Does `stopPropagation` and `preventDefault` at the same time.
2889function stop(e) {
2890	preventDefault(e);
2891	stopPropagation(e);
2892	return this;
2893}
2894
2895// @function getMousePosition(ev: DOMEvent, container?: HTMLElement): Point
2896// Gets normalized mouse position from a DOM event relative to the
2897// `container` (border excluded) or to the whole page if not specified.
2898function getMousePosition(e, container) {
2899	if (!container) {
2900		return new Point(e.clientX, e.clientY);
2901	}
2902
2903	var scale = getScale(container),
2904	    offset = scale.boundingClientRect; // left and top  values are in page scale (like the event clientX/Y)
2905
2906	return new Point(
2907		// offset.left/top values are in page scale (like clientX/Y),
2908		// whereas clientLeft/Top (border width) values are the original values (before CSS scale applies).
2909		(e.clientX - offset.left) / scale.x - container.clientLeft,
2910		(e.clientY - offset.top) / scale.y - container.clientTop
2911	);
2912}
2913
2914// Chrome on Win scrolls double the pixels as in other platforms (see #4538),
2915// and Firefox scrolls device pixels, not CSS pixels
2916var wheelPxFactor =
2917	(win && chrome) ? 2 * window.devicePixelRatio :
2918	gecko ? window.devicePixelRatio : 1;
2919
2920// @function getWheelDelta(ev: DOMEvent): Number
2921// Gets normalized wheel delta from a mousewheel DOM event, in vertical
2922// pixels scrolled (negative if scrolling down).
2923// Events from pointing devices without precise scrolling are mapped to
2924// a best guess of 60 pixels.
2925function getWheelDelta(e) {
2926	return (edge) ? e.wheelDeltaY / 2 : // Don't trust window-geometry-based delta
2927	       (e.deltaY && e.deltaMode === 0) ? -e.deltaY / wheelPxFactor : // Pixels
2928	       (e.deltaY && e.deltaMode === 1) ? -e.deltaY * 20 : // Lines
2929	       (e.deltaY && e.deltaMode === 2) ? -e.deltaY * 60 : // Pages
2930	       (e.deltaX || e.deltaZ) ? 0 :	// Skip horizontal/depth wheel events
2931	       e.wheelDelta ? (e.wheelDeltaY || e.wheelDelta) / 2 : // Legacy IE pixels
2932	       (e.detail && Math.abs(e.detail) < 32765) ? -e.detail * 20 : // Legacy Moz lines
2933	       e.detail ? e.detail / -32765 * 60 : // Legacy Moz pages
2934	       0;
2935}
2936
2937var skipEvents = {};
2938
2939function fakeStop(e) {
2940	// fakes stopPropagation by setting a special event flag, checked/reset with skipped(e)
2941	skipEvents[e.type] = true;
2942}
2943
2944function skipped(e) {
2945	var events = skipEvents[e.type];
2946	// reset when checking, as it's only used in map container and propagates outside of the map
2947	skipEvents[e.type] = false;
2948	return events;
2949}
2950
2951// check if element really left/entered the event target (for mouseenter/mouseleave)
2952function isExternalTarget(el, e) {
2953
2954	var related = e.relatedTarget;
2955
2956	if (!related) { return true; }
2957
2958	try {
2959		while (related && (related !== el)) {
2960			related = related.parentNode;
2961		}
2962	} catch (err) {
2963		return false;
2964	}
2965	return (related !== el);
2966}
2967
2968var lastClick;
2969
2970// this is a horrible workaround for a bug in Android where a single touch triggers two click events
2971function filterClick(e, handler) {
2972	var timeStamp = (e.timeStamp || (e.originalEvent && e.originalEvent.timeStamp)),
2973	    elapsed = lastClick && (timeStamp - lastClick);
2974
2975	// are they closer together than 500ms yet more than 100ms?
2976	// Android typically triggers them ~300ms apart while multiple listeners
2977	// on the same event should be triggered far faster;
2978	// or check if click is simulated on the element, and if it is, reject any non-simulated events
2979
2980	if ((elapsed && elapsed > 100 && elapsed < 500) || (e.target._simulatedClick && !e._simulated)) {
2981		stop(e);
2982		return;
2983	}
2984	lastClick = timeStamp;
2985
2986	handler(e);
2987}
2988
2989
2990
2991
2992var DomEvent = (Object.freeze || Object)({
2993	on: on,
2994	off: off,
2995	stopPropagation: stopPropagation,
2996	disableScrollPropagation: disableScrollPropagation,
2997	disableClickPropagation: disableClickPropagation,
2998	preventDefault: preventDefault,
2999	stop: stop,
3000	getMousePosition: getMousePosition,
3001	getWheelDelta: getWheelDelta,
3002	fakeStop: fakeStop,
3003	skipped: skipped,
3004	isExternalTarget: isExternalTarget,
3005	addListener: on,
3006	removeListener: off
3007});
3008
3009/*
3010 * @class PosAnimation
3011 * @aka L.PosAnimation
3012 * @inherits Evented
3013 * Used internally for panning animations, utilizing CSS3 Transitions for modern browsers and a timer fallback for IE6-9.
3014 *
3015 * @example
3016 * ```js
3017 * var fx = new L.PosAnimation();
3018 * fx.run(el, [300, 500], 0.5);
3019 * ```
3020 *
3021 * @constructor L.PosAnimation()
3022 * Creates a `PosAnimation` object.
3023 *
3024 */
3025
3026var PosAnimation = Evented.extend({
3027
3028	// @method run(el: HTMLElement, newPos: Point, duration?: Number, easeLinearity?: Number)
3029	// Run an animation of a given element to a new position, optionally setting
3030	// duration in seconds (`0.25` by default) and easing linearity factor (3rd
3031	// argument of the [cubic bezier curve](http://cubic-bezier.com/#0,0,.5,1),
3032	// `0.5` by default).
3033	run: function (el, newPos, duration, easeLinearity) {
3034		this.stop();
3035
3036		this._el = el;
3037		this._inProgress = true;
3038		this._duration = duration || 0.25;
3039		this._easeOutPower = 1 / Math.max(easeLinearity || 0.5, 0.2);
3040
3041		this._startPos = getPosition(el);
3042		this._offset = newPos.subtract(this._startPos);
3043		this._startTime = +new Date();
3044
3045		// @event start: Event
3046		// Fired when the animation starts
3047		this.fire('start');
3048
3049		this._animate();
3050	},
3051
3052	// @method stop()
3053	// Stops the animation (if currently running).
3054	stop: function () {
3055		if (!this._inProgress) { return; }
3056
3057		this._step(true);
3058		this._complete();
3059	},
3060
3061	_animate: function () {
3062		// animation loop
3063		this._animId = requestAnimFrame(this._animate, this);
3064		this._step();
3065	},
3066
3067	_step: function (round) {
3068		var elapsed = (+new Date()) - this._startTime,
3069		    duration = this._duration * 1000;
3070
3071		if (elapsed < duration) {
3072			this._runFrame(this._easeOut(elapsed / duration), round);
3073		} else {
3074			this._runFrame(1);
3075			this._complete();
3076		}
3077	},
3078
3079	_runFrame: function (progress, round) {
3080		var pos = this._startPos.add(this._offset.multiplyBy(progress));
3081		if (round) {
3082			pos._round();
3083		}
3084		setPosition(this._el, pos);
3085
3086		// @event step: Event
3087		// Fired continuously during the animation.
3088		this.fire('step');
3089	},
3090
3091	_complete: function () {
vendor: 18,113 bytes, lines 3092-3664
3092		cancelAnimFrame(this._animId);
3093
3094		this._inProgress = false;
3095		// @event end: Event
3096		// Fired when the animation ends.
3097		this.fire('end');
3098	},
3099
3100	_easeOut: function (t) {
3101		return 1 - Math.pow(1 - t, this._easeOutPower);
3102	}
3103});
3104
3105/*
3106 * @class Map
3107 * @aka L.Map
3108 * @inherits Evented
3109 *
3110 * The central class of the API — it is used to create a map on a page and manipulate it.
3111 *
3112 * @example
3113 *
3114 * ```js
3115 * // initialize the map on the "map" div with a given center and zoom
3116 * var map = L.map('map', {
3117 * 	center: [51.505, -0.09],
3118 * 	zoom: 13
3119 * });
3120 * ```
3121 *
3122 */
3123
3124var Map = Evented.extend({
3125
3126	options: {
3127		// @section Map State Options
3128		// @option crs: CRS = L.CRS.EPSG3857
3129		// The [Coordinate Reference System](#crs) to use. Don't change this if you're not
3130		// sure what it means.
3131		crs: EPSG3857,
3132
3133		// @option center: LatLng = undefined
3134		// Initial geographic center of the map
3135		center: undefined,
3136
3137		// @option zoom: Number = undefined
3138		// Initial map zoom level
3139		zoom: undefined,
3140
3141		// @option minZoom: Number = *
3142		// Minimum zoom level of the map.
3143		// If not specified and at least one `GridLayer` or `TileLayer` is in the map,
3144		// the lowest of their `minZoom` options will be used instead.
3145		minZoom: undefined,
3146
3147		// @option maxZoom: Number = *
3148		// Maximum zoom level of the map.
3149		// If not specified and at least one `GridLayer` or `TileLayer` is in the map,
3150		// the highest of their `maxZoom` options will be used instead.
3151		maxZoom: undefined,
3152
3153		// @option layers: Layer[] = []
3154		// Array of layers that will be added to the map initially
3155		layers: [],
3156
3157		// @option maxBounds: LatLngBounds = null
3158		// When this option is set, the map restricts the view to the given
3159		// geographical bounds, bouncing the user back if the user tries to pan
3160		// outside the view. To set the restriction dynamically, use
3161		// [`setMaxBounds`](#map-setmaxbounds) method.
3162		maxBounds: undefined,
3163
3164		// @option renderer: Renderer = *
3165		// The default method for drawing vector layers on the map. `L.SVG`
3166		// or `L.Canvas` by default depending on browser support.
3167		renderer: undefined,
3168
3169
3170		// @section Animation Options
3171		// @option zoomAnimation: Boolean = true
3172		// Whether the map zoom animation is enabled. By default it's enabled
3173		// in all browsers that support CSS3 Transitions except Android.
3174		zoomAnimation: true,
3175
3176		// @option zoomAnimationThreshold: Number = 4
3177		// Won't animate zoom if the zoom difference exceeds this value.
3178		zoomAnimationThreshold: 4,
3179
3180		// @option fadeAnimation: Boolean = true
3181		// Whether the tile fade animation is enabled. By default it's enabled
3182		// in all browsers that support CSS3 Transitions except Android.
3183		fadeAnimation: true,
3184
3185		// @option markerZoomAnimation: Boolean = true
3186		// Whether markers animate their zoom with the zoom animation, if disabled
3187		// they will disappear for the length of the animation. By default it's
3188		// enabled in all browsers that support CSS3 Transitions except Android.
3189		markerZoomAnimation: true,
3190
3191		// @option transform3DLimit: Number = 2^23
3192		// Defines the maximum size of a CSS translation transform. The default
3193		// value should not be changed unless a web browser positions layers in
3194		// the wrong place after doing a large `panBy`.
3195		transform3DLimit: 8388608, // Precision limit of a 32-bit float
3196
3197		// @section Interaction Options
3198		// @option zoomSnap: Number = 1
3199		// Forces the map's zoom level to always be a multiple of this, particularly
3200		// right after a [`fitBounds()`](#map-fitbounds) or a pinch-zoom.
3201		// By default, the zoom level snaps to the nearest integer; lower values
3202		// (e.g. `0.5` or `0.1`) allow for greater granularity. A value of `0`
3203		// means the zoom level will not be snapped after `fitBounds` or a pinch-zoom.
3204		zoomSnap: 1,
3205
3206		// @option zoomDelta: Number = 1
3207		// Controls how much the map's zoom level will change after a
3208		// [`zoomIn()`](#map-zoomin), [`zoomOut()`](#map-zoomout), pressing `+`
3209		// or `-` on the keyboard, or using the [zoom controls](#control-zoom).
3210		// Values smaller than `1` (e.g. `0.5`) allow for greater granularity.
3211		zoomDelta: 1,
3212
3213		// @option trackResize: Boolean = true
3214		// Whether the map automatically handles browser window resize to update itself.
3215		trackResize: true
3216	},
3217
3218	initialize: function (id, options) { // (HTMLElement or String, Object)
3219		options = setOptions(this, options);
3220
3221		this._initContainer(id);
3222		this._initLayout();
3223
3224		// hack for https://github.com/Leaflet/Leaflet/issues/1980
3225		this._onResize = bind(this._onResize, this);
3226
3227		this._initEvents();
3228
3229		if (options.maxBounds) {
3230			this.setMaxBounds(options.maxBounds);
3231		}
3232
3233		if (options.zoom !== undefined) {
3234			this._zoom = this._limitZoom(options.zoom);
3235		}
3236
3237		if (options.center && options.zoom !== undefined) {
3238			this.setView(toLatLng(options.center), options.zoom, {reset: true});
3239		}
3240
3241		this._handlers = [];
3242		this._layers = {};
3243		this._zoomBoundLayers = {};
3244		this._sizeChanged = true;
3245
3246		this.callInitHooks();
3247
3248		// don't animate on browsers without hardware-accelerated transitions or old Android/Opera
3249		this._zoomAnimated = TRANSITION && any3d && !mobileOpera &&
3250				this.options.zoomAnimation;
3251
3252		// zoom transitions run with the same duration for all layers, so if one of transitionend events
3253		// happens after starting zoom animation (propagating to the map pane), we know that it ended globally
3254		if (this._zoomAnimated) {
3255			this._createAnimProxy();
3256			on(this._proxy, TRANSITION_END, this._catchTransitionEnd, this);
3257		}
3258
3259		this._addLayers(this.options.layers);
3260	},
3261
3262
3263	// @section Methods for modifying map state
3264
3265	// @method setView(center: LatLng, zoom: Number, options?: Zoom/pan options): this
3266	// Sets the view of the map (geographical center and zoom) with the given
3267	// animation options.
3268	setView: function (center, zoom, options) {
3269
3270		zoom = zoom === undefined ? this._zoom : this._limitZoom(zoom);
3271		center = this._limitCenter(toLatLng(center), zoom, this.options.maxBounds);
3272		options = options || {};
3273
3274		this._stop();
3275
3276		if (this._loaded && !options.reset && options !== true) {
3277
3278			if (options.animate !== undefined) {
3279				options.zoom = extend({animate: options.animate}, options.zoom);
3280				options.pan = extend({animate: options.animate, duration: options.duration}, options.pan);
3281			}
3282
3283			// try animating pan or zoom
3284			var moved = (this._zoom !== zoom) ?
3285				this._tryAnimatedZoom && this._tryAnimatedZoom(center, zoom, options.zoom) :
3286				this._tryAnimatedPan(center, options.pan);
3287
3288			if (moved) {
3289				// prevent resize handler call, the view will refresh after animation anyway
3290				clearTimeout(this._sizeTimer);
3291				return this;
3292			}
3293		}
3294
3295		// animation didn't start, just reset the map view
3296		this._resetView(center, zoom);
3297
3298		return this;
3299	},
3300
3301	// @method setZoom(zoom: Number, options?: Zoom/pan options): this
3302	// Sets the zoom of the map.
3303	setZoom: function (zoom, options) {
3304		if (!this._loaded) {
3305			this._zoom = zoom;
3306			return this;
3307		}
3308		return this.setView(this.getCenter(), zoom, {zoom: options});
3309	},
3310
3311	// @method zoomIn(delta?: Number, options?: Zoom options): this
3312	// Increases the zoom of the map by `delta` ([`zoomDelta`](#map-zoomdelta) by default).
3313	zoomIn: function (delta, options) {
3314		delta = delta || (any3d ? this.options.zoomDelta : 1);
3315		return this.setZoom(this._zoom + delta, options);
3316	},
3317
3318	// @method zoomOut(delta?: Number, options?: Zoom options): this
3319	// Decreases the zoom of the map by `delta` ([`zoomDelta`](#map-zoomdelta) by default).
3320	zoomOut: function (delta, options) {
3321		delta = delta || (any3d ? this.options.zoomDelta : 1);
3322		return this.setZoom(this._zoom - delta, options);
3323	},
3324
3325	// @method setZoomAround(latlng: LatLng, zoom: Number, options: Zoom options): this
3326	// Zooms the map while keeping a specified geographical point on the map
3327	// stationary (e.g. used internally for scroll zoom and double-click zoom).
3328	// @alternative
3329	// @method setZoomAround(offset: Point, zoom: Number, options: Zoom options): this
3330	// Zooms the map while keeping a specified pixel on the map (relative to the top-left corner) stationary.
3331	setZoomAround: function (latlng, zoom, options) {
3332		var scale = this.getZoomScale(zoom),
3333		    viewHalf = this.getSize().divideBy(2),
3334		    containerPoint = latlng instanceof Point ? latlng : this.latLngToContainerPoint(latlng),
3335
3336		    centerOffset = containerPoint.subtract(viewHalf).multiplyBy(1 - 1 / scale),
3337		    newCenter = this.containerPointToLatLng(viewHalf.add(centerOffset));
3338
3339		return this.setView(newCenter, zoom, {zoom: options});
3340	},
3341
3342	_getBoundsCenterZoom: function (bounds, options) {
3343
3344		options = options || {};
3345		bounds = bounds.getBounds ? bounds.getBounds() : toLatLngBounds(bounds);
3346
3347		var paddingTL = toPoint(options.paddingTopLeft || options.padding || [0, 0]),
3348		    paddingBR = toPoint(options.paddingBottomRight || options.padding || [0, 0]),
3349
3350		    zoom = this.getBoundsZoom(bounds, false, paddingTL.add(paddingBR));
3351
3352		zoom = (typeof options.maxZoom === 'number') ? Math.min(options.maxZoom, zoom) : zoom;
3353
3354		if (zoom === Infinity) {
3355			return {
3356				center: bounds.getCenter(),
3357				zoom: zoom
3358			};
3359		}
3360
3361		var paddingOffset = paddingBR.subtract(paddingTL).divideBy(2),
3362
3363		    swPoint = this.project(bounds.getSouthWest(), zoom),
3364		    nePoint = this.project(bounds.getNorthEast(), zoom),
3365		    center = this.unproject(swPoint.add(nePoint).divideBy(2).add(paddingOffset), zoom);
3366
3367		return {
3368			center: center,
3369			zoom: zoom
3370		};
3371	},
3372
3373	// @method fitBounds(bounds: LatLngBounds, options?: fitBounds options): this
3374	// Sets a map view that contains the given geographical bounds with the
3375	// maximum zoom level possible.
3376	fitBounds: function (bounds, options) {
3377
3378		bounds = toLatLngBounds(bounds);
3379
3380		if (!bounds.isValid()) {
3381			throw new Error('Bounds are not valid.');
3382		}
3383
3384		var target = this._getBoundsCenterZoom(bounds, options);
3385		return this.setView(target.center, target.zoom, options);
3386	},
3387
3388	// @method fitWorld(options?: fitBounds options): this
3389	// Sets a map view that mostly contains the whole world with the maximum
3390	// zoom level possible.
3391	fitWorld: function (options) {
3392		return this.fitBounds([[-90, -180], [90, 180]], options);
3393	},
3394
3395	// @method panTo(latlng: LatLng, options?: Pan options): this
3396	// Pans the map to a given center.
3397	panTo: function (center, options) { // (LatLng)
3398		return this.setView(center, this._zoom, {pan: options});
3399	},
3400
3401	// @method panBy(offset: Point, options?: Pan options): this
3402	// Pans the map by a given number of pixels (animated).
3403	panBy: function (offset, options) {
3404		offset = toPoint(offset).round();
3405		options = options || {};
3406
3407		if (!offset.x && !offset.y) {
3408			return this.fire('moveend');
3409		}
3410		// If we pan too far, Chrome gets issues with tiles
3411		// and makes them disappear or appear in the wrong place (slightly offset) #2602
3412		if (options.animate !== true && !this.getSize().contains(offset)) {
3413			this._resetView(this.unproject(this.project(this.getCenter()).add(offset)), this.getZoom());
3414			return this;
3415		}
3416
3417		if (!this._panAnim) {
3418			this._panAnim = new PosAnimation();
3419
3420			this._panAnim.on({
3421				'step': this._onPanTransitionStep,
3422				'end': this._onPanTransitionEnd
3423			}, this);
3424		}
3425
3426		// don't fire movestart if animating inertia
3427		if (!options.noMoveStart) {
3428			this.fire('movestart');
3429		}
3430
3431		// animate pan unless animate: false specified
3432		if (options.animate !== false) {
3433			addClass(this._mapPane, 'leaflet-pan-anim');
3434
3435			var newPos = this._getMapPanePos().subtract(offset).round();
3436			this._panAnim.run(this._mapPane, newPos, options.duration || 0.25, options.easeLinearity);
3437		} else {
3438			this._rawPanBy(offset);
3439			this.fire('move').fire('moveend');
3440		}
3441
3442		return this;
3443	},
3444
3445	// @method flyTo(latlng: LatLng, zoom?: Number, options?: Zoom/pan options): this
3446	// Sets the view of the map (geographical center and zoom) performing a smooth
3447	// pan-zoom animation.
3448	flyTo: function (targetCenter, targetZoom, options) {
3449
3450		options = options || {};
3451		if (options.animate === false || !any3d) {
3452			return this.setView(targetCenter, targetZoom, options);
3453		}
3454
3455		this._stop();
3456
3457		var from = this.project(this.getCenter()),
3458		    to = this.project(targetCenter),
3459		    size = this.getSize(),
3460		    startZoom = this._zoom;
3461
3462		targetCenter = toLatLng(targetCenter);
3463		targetZoom = targetZoom === undefined ? startZoom : targetZoom;
3464
3465		var w0 = Math.max(size.x, size.y),
3466		    w1 = w0 * this.getZoomScale(startZoom, targetZoom),
3467		    u1 = (to.distanceTo(from)) || 1,
3468		    rho = 1.42,
3469		    rho2 = rho * rho;
3470
3471		function r(i) {
3472			var s1 = i ? -1 : 1,
3473			    s2 = i ? w1 : w0,
3474			    t1 = w1 * w1 - w0 * w0 + s1 * rho2 * rho2 * u1 * u1,
3475			    b1 = 2 * s2 * rho2 * u1,
3476			    b = t1 / b1,
3477			    sq = Math.sqrt(b * b + 1) - b;
3478
3479			    // workaround for floating point precision bug when sq = 0, log = -Infinite,
3480			    // thus triggering an infinite loop in flyTo
3481			    var log = sq < 0.000000001 ? -18 : Math.log(sq);
3482
3483			return log;
3484		}
3485
3486		function sinh(n) { return (Math.exp(n) - Math.exp(-n)) / 2; }
3487		function cosh(n) { return (Math.exp(n) + Math.exp(-n)) / 2; }
3488		function tanh(n) { return sinh(n) / cosh(n); }
3489
3490		var r0 = r(0);
3491
3492		function w(s) { return w0 * (cosh(r0) / cosh(r0 + rho * s)); }
3493		function u(s) { return w0 * (cosh(r0) * tanh(r0 + rho * s) - sinh(r0)) / rho2; }
3494
3495		function easeOut(t) { return 1 - Math.pow(1 - t, 1.5); }
3496
3497		var start = Date.now(),
3498		    S = (r(1) - r0) / rho,
3499		    duration = options.duration ? 1000 * options.duration : 1000 * S * 0.8;
3500
3501		function frame() {
3502			var t = (Date.now() - start) / duration,
3503			    s = easeOut(t) * S;
3504
3505			if (t <= 1) {
3506				this._flyToFrame = requestAnimFrame(frame, this);
3507
3508				this._move(
3509					this.unproject(from.add(to.subtract(from).multiplyBy(u(s) / u1)), startZoom),
3510					this.getScaleZoom(w0 / w(s), startZoom),
3511					{flyTo: true});
3512
3513			} else {
3514				this
3515					._move(targetCenter, targetZoom)
3516					._moveEnd(true);
3517			}
3518		}
3519
3520		this._moveStart(true, options.noMoveStart);
3521
3522		frame.call(this);
3523		return this;
3524	},
3525
3526	// @method flyToBounds(bounds: LatLngBounds, options?: fitBounds options): this
3527	// Sets the view of the map with a smooth animation like [`flyTo`](#map-flyto),
3528	// but takes a bounds parameter like [`fitBounds`](#map-fitbounds).
3529	flyToBounds: function (bounds, options) {
3530		var target = this._getBoundsCenterZoom(bounds, options);
3531		return this.flyTo(target.center, target.zoom, options);
3532	},
3533
3534	// @method setMaxBounds(bounds: Bounds): this
3535	// Restricts the map view to the given bounds (see the [maxBounds](#map-maxbounds) option).
3536	setMaxBounds: function (bounds) {
3537		bounds = toLatLngBounds(bounds);
3538
3539		if (!bounds.isValid()) {
3540			this.options.maxBounds = null;
3541			return this.off('moveend', this._panInsideMaxBounds);
3542		} else if (this.options.maxBounds) {
3543			this.off('moveend', this._panInsideMaxBounds);
3544		}
3545
3546		this.options.maxBounds = bounds;
3547
3548		if (this._loaded) {
3549			this._panInsideMaxBounds();
3550		}
3551
3552		return this.on('moveend', this._panInsideMaxBounds);
3553	},
3554
3555	// @method setMinZoom(zoom: Number): this
3556	// Sets the lower limit for the available zoom levels (see the [minZoom](#map-minzoom) option).
3557	setMinZoom: function (zoom) {
3558		var oldZoom = this.options.minZoom;
3559		this.options.minZoom = zoom;
3560
3561		if (this._loaded && oldZoom !== zoom) {
3562			this.fire('zoomlevelschange');
3563
3564			if (this.getZoom() < this.options.minZoom) {
3565				return this.setZoom(zoom);
3566			}
3567		}
3568
3569		return this;
3570	},
3571
3572	// @method setMaxZoom(zoom: Number): this
3573	// Sets the upper limit for the available zoom levels (see the [maxZoom](#map-maxzoom) option).
3574	setMaxZoom: function (zoom) {
3575		var oldZoom = this.options.maxZoom;
3576		this.options.maxZoom = zoom;
3577
3578		if (this._loaded && oldZoom !== zoom) {
3579			this.fire('zoomlevelschange');
3580
3581			if (this.getZoom() > this.options.maxZoom) {
3582				return this.setZoom(zoom);
3583			}
3584		}
3585
3586		return this;
3587	},
3588
3589	// @method panInsideBounds(bounds: LatLngBounds, options?: Pan options): this
3590	// Pans the map to the closest view that would lie inside the given bounds (if it's not already), controlling the animation using the options specific, if any.
3591	panInsideBounds: function (bounds, options) {
3592		this._enforcingBounds = true;
3593		var center = this.getCenter(),
3594		    newCenter = this._limitCenter(center, this._zoom, toLatLngBounds(bounds));
3595
3596		if (!center.equals(newCenter)) {
3597			this.panTo(newCenter, options);
3598		}
3599
3600		this._enforcingBounds = false;
3601		return this;
3602	},
3603
3604	// @method invalidateSize(options: Zoom/pan options): this
3605	// Checks if the map container size changed and updates the map if so —
3606	// call it after you've changed the map size dynamically, also animating
3607	// pan by default. If `options.pan` is `false`, panning will not occur.
3608	// If `options.debounceMoveend` is `true`, it will delay `moveend` event so
3609	// that it doesn't happen often even if the method is called many
3610	// times in a row.
3611
3612	// @alternative
3613	// @method invalidateSize(animate: Boolean): this
3614	// Checks if the map container size changed and updates the map if so —
3615	// call it after you've changed the map size dynamically, also animating
3616	// pan by default.
3617	invalidateSize: function (options) {
3618		if (!this._loaded) { return this; }
3619
3620		options = extend({
3621			animate: false,
3622			pan: true
3623		}, options === true ? {animate: true} : options);
3624
3625		var oldSize = this.getSize();
3626		this._sizeChanged = true;
3627		this._lastCenter = null;
3628
3629		var newSize = this.getSize(),
3630		    oldCenter = oldSize.divideBy(2).round(),
3631		    newCenter = newSize.divideBy(2).round(),
3632		    offset = oldCenter.subtract(newCenter);
3633
3634		if (!offset.x && !offset.y) { return this; }
3635
3636		if (options.animate && options.pan) {
3637			this.panBy(offset);
3638
3639		} else {
3640			if (options.pan) {
3641				this._rawPanBy(offset);
3642			}
3643
3644			this.fire('move');
3645
3646			if (options.debounceMoveend) {
3647				clearTimeout(this._sizeTimer);
3648				this._sizeTimer = setTimeout(bind(this.fire, this, 'moveend'), 200);
3649			} else {
3650				this.fire('moveend');
3651			}
3652		}
3653
3654		// @section Map state change events
3655		// @event resize: ResizeEvent
3656		// Fired when the map is resized.
3657		return this.fire('resize', {
3658			oldSize: oldSize,
3659			newSize: newSize
3660		});
3661	},
3662
3663	// @section Methods for modifying map state
3664	// @method stop(): this
3665	// Stops the currently running `panTo` or `flyTo` animation, if any.
3666	stop: function () {
3667		this.setZoom(this._limitZoom(this._zoom));
3668		if (!this.options.zoomSnap) {
3669			this.fire('viewreset');
3670		}
3671		return this._stop();
3672	},
3673
3674	// @section Geolocation methods
3675	// @method locate(options?: Locate options): this
3676	// Tries to locate the user using the Geolocation API, firing a [`locationfound`](#map-locationfound)
3677	// event with location data on success or a [`locationerror`](#map-locationerror) event on failure,
3678	// and optionally sets the map view to the user's location with respect to
3679	// detection accuracy (or to the world view if geolocation failed).
3680	// Note that, if your page doesn't use HTTPS, this method will fail in
3681	// modern browsers ([Chrome 50 and newer](https://sites.google.com/a/chromium.org/dev/Home/chromium-security/deprecating-powerful-features-on-insecure-origins))
3682	// See `Locate options` for more details.
3683	locate: function (options) {
3684
3685		options = this._locateOptions = extend({
3686			timeout: 10000,
3687			watch: false
3688			// setView: false
3689			// maxZoom: <Number>
3690			// maximumAge: 0
vendor: 21,622 bytes, lines 3691-4360
3691			// enableHighAccuracy: false
3692		}, options);
3693
3694		if (!('geolocation' in navigator)) {
3695			this._handleGeolocationError({
3696				code: 0,
3697				message: 'Geolocation not supported.'
3698			});
3699			return this;
3700		}
3701
3702		var onResponse = bind(this._handleGeolocationResponse, this),
3703		    onError = bind(this._handleGeolocationError, this);
3704
3705		if (options.watch) {
3706			this._locationWatchId =
3707			        navigator.geolocation.watchPosition(onResponse, onError, options);
3708		} else {
3709			navigator.geolocation.getCurrentPosition(onResponse, onError, options);
3710		}
3711		return this;
3712	},
3713
3714	// @method stopLocate(): this
3715	// Stops watching location previously initiated by `map.locate({watch: true})`
3716	// and aborts resetting the map view if map.locate was called with
3717	// `{setView: true}`.
3718	stopLocate: function () {
3719		if (navigator.geolocation && navigator.geolocation.clearWatch) {
3720			navigator.geolocation.clearWatch(this._locationWatchId);
3721		}
3722		if (this._locateOptions) {
3723			this._locateOptions.setView = false;
3724		}
3725		return this;
3726	},
3727
3728	_handleGeolocationError: function (error) {
3729		var c = error.code,
3730		    message = error.message ||
3731		            (c === 1 ? 'permission denied' :
3732		            (c === 2 ? 'position unavailable' : 'timeout'));
3733
3734		if (this._locateOptions.setView && !this._loaded) {
3735			this.fitWorld();
3736		}
3737
3738		// @section Location events
3739		// @event locationerror: ErrorEvent
3740		// Fired when geolocation (using the [`locate`](#map-locate) method) failed.
3741		this.fire('locationerror', {
3742			code: c,
3743			message: 'Geolocation error: ' + message + '.'
3744		});
3745	},
3746
3747	_handleGeolocationResponse: function (pos) {
3748		var lat = pos.coords.latitude,
3749		    lng = pos.coords.longitude,
3750		    latlng = new LatLng(lat, lng),
3751		    bounds = latlng.toBounds(pos.coords.accuracy * 2),
3752		    options = this._locateOptions;
3753
3754		if (options.setView) {
3755			var zoom = this.getBoundsZoom(bounds);
3756			this.setView(latlng, options.maxZoom ? Math.min(zoom, options.maxZoom) : zoom);
3757		}
3758
3759		var data = {
3760			latlng: latlng,
3761			bounds: bounds,
3762			timestamp: pos.timestamp
3763		};
3764
3765		for (var i in pos.coords) {
3766			if (typeof pos.coords[i] === 'number') {
3767				data[i] = pos.coords[i];
3768			}
3769		}
3770
3771		// @event locationfound: LocationEvent
3772		// Fired when geolocation (using the [`locate`](#map-locate) method)
3773		// went successfully.
3774		this.fire('locationfound', data);
3775	},
3776
3777	// TODO Appropriate docs section?
3778	// @section Other Methods
3779	// @method addHandler(name: String, HandlerClass: Function): this
3780	// Adds a new `Handler` to the map, given its name and constructor function.
3781	addHandler: function (name, HandlerClass) {
3782		if (!HandlerClass) { return this; }
3783
3784		var handler = this[name] = new HandlerClass(this);
3785
3786		this._handlers.push(handler);
3787
3788		if (this.options[name]) {
3789			handler.enable();
3790		}
3791
3792		return this;
3793	},
3794
3795	// @method remove(): this
3796	// Destroys the map and clears all related event listeners.
3797	remove: function () {
3798
3799		this._initEvents(true);
3800
3801		if (this._containerId !== this._container._leaflet_id) {
3802			throw new Error('Map container is being reused by another instance');
3803		}
3804
3805		try {
3806			// throws error in IE6-8
3807			delete this._container._leaflet_id;
3808			delete this._containerId;
3809		} catch (e) {
3810			/*eslint-disable */
3811			this._container._leaflet_id = undefined;
3812			/* eslint-enable */
3813			this._containerId = undefined;
3814		}
3815
3816		if (this._locationWatchId !== undefined) {
3817			this.stopLocate();
3818		}
3819
3820		this._stop();
3821
3822		remove(this._mapPane);
3823
3824		if (this._clearControlPos) {
3825			this._clearControlPos();
3826		}
3827		if (this._resizeRequest) {
3828			cancelAnimFrame(this._resizeRequest);
3829			this._resizeRequest = null;
3830		}
3831
3832		this._clearHandlers();
3833
3834		if (this._loaded) {
3835			// @section Map state change events
3836			// @event unload: Event
3837			// Fired when the map is destroyed with [remove](#map-remove) method.
3838			this.fire('unload');
3839		}
3840
3841		var i;
3842		for (i in this._layers) {
3843			this._layers[i].remove();
3844		}
3845		for (i in this._panes) {
3846			remove(this._panes[i]);
3847		}
3848
3849		this._layers = [];
3850		this._panes = [];
3851		delete this._mapPane;
3852		delete this._renderer;
3853
3854		return this;
3855	},
3856
3857	// @section Other Methods
3858	// @method createPane(name: String, container?: HTMLElement): HTMLElement
3859	// Creates a new [map pane](#map-pane) with the given name if it doesn't exist already,
3860	// then returns it. The pane is created as a child of `container`, or
3861	// as a child of the main map pane if not set.
3862	createPane: function (name, container) {
3863		var className = 'leaflet-pane' + (name ? ' leaflet-' + name.replace('Pane', '') + '-pane' : ''),
3864		    pane = create$1('div', className, container || this._mapPane);
3865
3866		if (name) {
3867			this._panes[name] = pane;
3868		}
3869		return pane;
3870	},
3871
3872	// @section Methods for Getting Map State
3873
3874	// @method getCenter(): LatLng
3875	// Returns the geographical center of the map view
3876	getCenter: function () {
3877		this._checkIfLoaded();
3878
3879		if (this._lastCenter && !this._moved()) {
3880			return this._lastCenter;
3881		}
3882		return this.layerPointToLatLng(this._getCenterLayerPoint());
3883	},
3884
3885	// @method getZoom(): Number
3886	// Returns the current zoom level of the map view
3887	getZoom: function () {
3888		return this._zoom;
3889	},
3890
3891	// @method getBounds(): LatLngBounds
3892	// Returns the geographical bounds visible in the current map view
3893	getBounds: function () {
3894		var bounds = this.getPixelBounds(),
3895		    sw = this.unproject(bounds.getBottomLeft()),
3896		    ne = this.unproject(bounds.getTopRight());
3897
3898		return new LatLngBounds(sw, ne);
3899	},
3900
3901	// @method getMinZoom(): Number
3902	// Returns the minimum zoom level of the map (if set in the `minZoom` option of the map or of any layers), or `0` by default.
3903	getMinZoom: function () {
3904		return this.options.minZoom === undefined ? this._layersMinZoom || 0 : this.options.minZoom;
3905	},
3906
3907	// @method getMaxZoom(): Number
3908	// Returns the maximum zoom level of the map (if set in the `maxZoom` option of the map or of any layers).
3909	getMaxZoom: function () {
3910		return this.options.maxZoom === undefined ?
3911			(this._layersMaxZoom === undefined ? Infinity : this._layersMaxZoom) :
3912			this.options.maxZoom;
3913	},
3914
3915	// @method getBoundsZoom(bounds: LatLngBounds, inside?: Boolean, padding?: Point): Number
3916	// Returns the maximum zoom level on which the given bounds fit to the map
3917	// view in its entirety. If `inside` (optional) is set to `true`, the method
3918	// instead returns the minimum zoom level on which the map view fits into
3919	// the given bounds in its entirety.
3920	getBoundsZoom: function (bounds, inside, padding) { // (LatLngBounds[, Boolean, Point]) -> Number
3921		bounds = toLatLngBounds(bounds);
3922		padding = toPoint(padding || [0, 0]);
3923
3924		var zoom = this.getZoom() || 0,
3925		    min = this.getMinZoom(),
3926		    max = this.getMaxZoom(),
3927		    nw = bounds.getNorthWest(),
3928		    se = bounds.getSouthEast(),
3929		    size = this.getSize().subtract(padding),
3930		    boundsSize = toBounds(this.project(se, zoom), this.project(nw, zoom)).getSize(),
3931		    snap = any3d ? this.options.zoomSnap : 1,
3932		    scalex = size.x / boundsSize.x,
3933		    scaley = size.y / boundsSize.y,
3934		    scale = inside ? Math.max(scalex, scaley) : Math.min(scalex, scaley);
3935
3936		zoom = this.getScaleZoom(scale, zoom);
3937
3938		if (snap) {
3939			zoom = Math.round(zoom / (snap / 100)) * (snap / 100); // don't jump if within 1% of a snap level
3940			zoom = inside ? Math.ceil(zoom / snap) * snap : Math.floor(zoom / snap) * snap;
3941		}
3942
3943		return Math.max(min, Math.min(max, zoom));
3944	},
3945
3946	// @method getSize(): Point
3947	// Returns the current size of the map container (in pixels).
3948	getSize: function () {
3949		if (!this._size || this._sizeChanged) {
3950			this._size = new Point(
3951				this._container.clientWidth || 0,
3952				this._container.clientHeight || 0);
3953
3954			this._sizeChanged = false;
3955		}
3956		return this._size.clone();
3957	},
3958
3959	// @method getPixelBounds(): Bounds
3960	// Returns the bounds of the current map view in projected pixel
3961	// coordinates (sometimes useful in layer and overlay implementations).
3962	getPixelBounds: function (center, zoom) {
3963		var topLeftPoint = this._getTopLeftPoint(center, zoom);
3964		return new Bounds(topLeftPoint, topLeftPoint.add(this.getSize()));
3965	},
3966
3967	// TODO: Check semantics - isn't the pixel origin the 0,0 coord relative to
3968	// the map pane? "left point of the map layer" can be confusing, specially
3969	// since there can be negative offsets.
3970	// @method getPixelOrigin(): Point
3971	// Returns the projected pixel coordinates of the top left point of
3972	// the map layer (useful in custom layer and overlay implementations).
3973	getPixelOrigin: function () {
3974		this._checkIfLoaded();
3975		return this._pixelOrigin;
3976	},
3977
3978	// @method getPixelWorldBounds(zoom?: Number): Bounds
3979	// Returns the world's bounds in pixel coordinates for zoom level `zoom`.
3980	// If `zoom` is omitted, the map's current zoom level is used.
3981	getPixelWorldBounds: function (zoom) {
3982		return this.options.crs.getProjectedBounds(zoom === undefined ? this.getZoom() : zoom);
3983	},
3984
3985	// @section Other Methods
3986
3987	// @method getPane(pane: String|HTMLElement): HTMLElement
3988	// Returns a [map pane](#map-pane), given its name or its HTML element (its identity).
3989	getPane: function (pane) {
3990		return typeof pane === 'string' ? this._panes[pane] : pane;
3991	},
3992
3993	// @method getPanes(): Object
3994	// Returns a plain object containing the names of all [panes](#map-pane) as keys and
3995	// the panes as values.
3996	getPanes: function () {
3997		return this._panes;
3998	},
3999
4000	// @method getContainer: HTMLElement
4001	// Returns the HTML element that contains the map.
4002	getContainer: function () {
4003		return this._container;
4004	},
4005
4006
4007	// @section Conversion Methods
4008
4009	// @method getZoomScale(toZoom: Number, fromZoom: Number): Number
4010	// Returns the scale factor to be applied to a map transition from zoom level
4011	// `fromZoom` to `toZoom`. Used internally to help with zoom animations.
4012	getZoomScale: function (toZoom, fromZoom) {
4013		// TODO replace with universal implementation after refactoring projections
4014		var crs = this.options.crs;
4015		fromZoom = fromZoom === undefined ? this._zoom : fromZoom;
4016		return crs.scale(toZoom) / crs.scale(fromZoom);
4017	},
4018
4019	// @method getScaleZoom(scale: Number, fromZoom: Number): Number
4020	// Returns the zoom level that the map would end up at, if it is at `fromZoom`
4021	// level and everything is scaled by a factor of `scale`. Inverse of
4022	// [`getZoomScale`](#map-getZoomScale).
4023	getScaleZoom: function (scale, fromZoom) {
4024		var crs = this.options.crs;
4025		fromZoom = fromZoom === undefined ? this._zoom : fromZoom;
4026		var zoom = crs.zoom(scale * crs.scale(fromZoom));
4027		return isNaN(zoom) ? Infinity : zoom;
4028	},
4029
4030	// @method project(latlng: LatLng, zoom: Number): Point
4031	// Projects a geographical coordinate `LatLng` according to the projection
4032	// of the map's CRS, then scales it according to `zoom` and the CRS's
4033	// `Transformation`. The result is pixel coordinate relative to
4034	// the CRS origin.
4035	project: function (latlng, zoom) {
4036		zoom = zoom === undefined ? this._zoom : zoom;
4037		return this.options.crs.latLngToPoint(toLatLng(latlng), zoom);
4038	},
4039
4040	// @method unproject(point: Point, zoom: Number): LatLng
4041	// Inverse of [`project`](#map-project).
4042	unproject: function (point, zoom) {
4043		zoom = zoom === undefined ? this._zoom : zoom;
4044		return this.options.crs.pointToLatLng(toPoint(point), zoom);
4045	},
4046
4047	// @method layerPointToLatLng(point: Point): LatLng
4048	// Given a pixel coordinate relative to the [origin pixel](#map-getpixelorigin),
4049	// returns the corresponding geographical coordinate (for the current zoom level).
4050	layerPointToLatLng: function (point) {
4051		var projectedPoint = toPoint(point).add(this.getPixelOrigin());
4052		return this.unproject(projectedPoint);
4053	},
4054
4055	// @method latLngToLayerPoint(latlng: LatLng): Point
4056	// Given a geographical coordinate, returns the corresponding pixel coordinate
4057	// relative to the [origin pixel](#map-getpixelorigin).
4058	latLngToLayerPoint: function (latlng) {
4059		var projectedPoint = this.project(toLatLng(latlng))._round();
4060		return projectedPoint._subtract(this.getPixelOrigin());
4061	},
4062
4063	// @method wrapLatLng(latlng: LatLng): LatLng
4064	// Returns a `LatLng` where `lat` and `lng` has been wrapped according to the
4065	// map's CRS's `wrapLat` and `wrapLng` properties, if they are outside the
4066	// CRS's bounds.
4067	// By default this means longitude is wrapped around the dateline so its
4068	// value is between -180 and +180 degrees.
4069	wrapLatLng: function (latlng) {
4070		return this.options.crs.wrapLatLng(toLatLng(latlng));
4071	},
4072
4073	// @method wrapLatLngBounds(bounds: LatLngBounds): LatLngBounds
4074	// Returns a `LatLngBounds` with the same size as the given one, ensuring that
4075	// its center is within the CRS's bounds.
4076	// By default this means the center longitude is wrapped around the dateline so its
4077	// value is between -180 and +180 degrees, and the majority of the bounds
4078	// overlaps the CRS's bounds.
4079	wrapLatLngBounds: function (latlng) {
4080		return this.options.crs.wrapLatLngBounds(toLatLngBounds(latlng));
4081	},
4082
4083	// @method distance(latlng1: LatLng, latlng2: LatLng): Number
4084	// Returns the distance between two geographical coordinates according to
4085	// the map's CRS. By default this measures distance in meters.
4086	distance: function (latlng1, latlng2) {
4087		return this.options.crs.distance(toLatLng(latlng1), toLatLng(latlng2));
4088	},
4089
4090	// @method containerPointToLayerPoint(point: Point): Point
4091	// Given a pixel coordinate relative to the map container, returns the corresponding
4092	// pixel coordinate relative to the [origin pixel](#map-getpixelorigin).
4093	containerPointToLayerPoint: function (point) { // (Point)
4094		return toPoint(point).subtract(this._getMapPanePos());
4095	},
4096
4097	// @method layerPointToContainerPoint(point: Point): Point
4098	// Given a pixel coordinate relative to the [origin pixel](#map-getpixelorigin),
4099	// returns the corresponding pixel coordinate relative to the map container.
4100	layerPointToContainerPoint: function (point) { // (Point)
4101		return toPoint(point).add(this._getMapPanePos());
4102	},
4103
4104	// @method containerPointToLatLng(point: Point): LatLng
4105	// Given a pixel coordinate relative to the map container, returns
4106	// the corresponding geographical coordinate (for the current zoom level).
4107	containerPointToLatLng: function (point) {
4108		var layerPoint = this.containerPointToLayerPoint(toPoint(point));
4109		return this.layerPointToLatLng(layerPoint);
4110	},
4111
4112	// @method latLngToContainerPoint(latlng: LatLng): Point
4113	// Given a geographical coordinate, returns the corresponding pixel coordinate
4114	// relative to the map container.
4115	latLngToContainerPoint: function (latlng) {
4116		return this.layerPointToContainerPoint(this.latLngToLayerPoint(toLatLng(latlng)));
4117	},
4118
4119	// @method mouseEventToContainerPoint(ev: MouseEvent): Point
4120	// Given a MouseEvent object, returns the pixel coordinate relative to the
4121	// map container where the event took place.
4122	mouseEventToContainerPoint: function (e) {
4123		return getMousePosition(e, this._container);
4124	},
4125
4126	// @method mouseEventToLayerPoint(ev: MouseEvent): Point
4127	// Given a MouseEvent object, returns the pixel coordinate relative to
4128	// the [origin pixel](#map-getpixelorigin) where the event took place.
4129	mouseEventToLayerPoint: function (e) {
4130		return this.containerPointToLayerPoint(this.mouseEventToContainerPoint(e));
4131	},
4132
4133	// @method mouseEventToLatLng(ev: MouseEvent): LatLng
4134	// Given a MouseEvent object, returns geographical coordinate where the
4135	// event took place.
4136	mouseEventToLatLng: function (e) { // (MouseEvent)
4137		return this.layerPointToLatLng(this.mouseEventToLayerPoint(e));
4138	},
4139
4140
4141	// map initialization methods
4142
4143	_initContainer: function (id) {
4144		var container = this._container = get(id);
4145
4146		if (!container) {
4147			throw new Error('Map container not found.');
4148		} else if (container._leaflet_id) {
4149			throw new Error('Map container is already initialized.');
4150		}
4151
4152		on(container, 'scroll', this._onScroll, this);
4153		this._containerId = stamp(container);
4154	},
4155
4156	_initLayout: function () {
4157		var container = this._container;
4158
4159		this._fadeAnimated = this.options.fadeAnimation && any3d;
4160
4161		addClass(container, 'leaflet-container' +
4162			(touch ? ' leaflet-touch' : '') +
4163			(retina ? ' leaflet-retina' : '') +
4164			(ielt9 ? ' leaflet-oldie' : '') +
4165			(safari ? ' leaflet-safari' : '') +
4166			(this._fadeAnimated ? ' leaflet-fade-anim' : ''));
4167
4168		var position = getStyle(container, 'position');
4169
4170		if (position !== 'absolute' && position !== 'relative' && position !== 'fixed') {
4171			container.style.position = 'relative';
4172		}
4173
4174		this._initPanes();
4175
4176		if (this._initControlPos) {
4177			this._initControlPos();
4178		}
4179	},
4180
4181	_initPanes: function () {
4182		var panes = this._panes = {};
4183		this._paneRenderers = {};
4184
4185		// @section
4186		//
4187		// Panes are DOM elements used to control the ordering of layers on the map. You
4188		// can access panes with [`map.getPane`](#map-getpane) or
4189		// [`map.getPanes`](#map-getpanes) methods. New panes can be created with the
4190		// [`map.createPane`](#map-createpane) method.
4191		//
4192		// Every map has the following default panes that differ only in zIndex.
4193		//
4194		// @pane mapPane: HTMLElement = 'auto'
4195		// Pane that contains all other map panes
4196
4197		this._mapPane = this.createPane('mapPane', this._container);
4198		setPosition(this._mapPane, new Point(0, 0));
4199
4200		// @pane tilePane: HTMLElement = 200
4201		// Pane for `GridLayer`s and `TileLayer`s
4202		this.createPane('tilePane');
4203		// @pane overlayPane: HTMLElement = 400
4204		// Pane for vectors (`Path`s, like `Polyline`s and `Polygon`s), `ImageOverlay`s and `VideoOverlay`s
4205		this.createPane('shadowPane');
4206		// @pane shadowPane: HTMLElement = 500
4207		// Pane for overlay shadows (e.g. `Marker` shadows)
4208		this.createPane('overlayPane');
4209		// @pane markerPane: HTMLElement = 600
4210		// Pane for `Icon`s of `Marker`s
4211		this.createPane('markerPane');
4212		// @pane tooltipPane: HTMLElement = 650
4213		// Pane for `Tooltip`s.
4214		this.createPane('tooltipPane');
4215		// @pane popupPane: HTMLElement = 700
4216		// Pane for `Popup`s.
4217		this.createPane('popupPane');
4218
4219		if (!this.options.markerZoomAnimation) {
4220			addClass(panes.markerPane, 'leaflet-zoom-hide');
4221			addClass(panes.shadowPane, 'leaflet-zoom-hide');
4222		}
4223	},
4224
4225
4226	// private methods that modify map state
4227
4228	// @section Map state change events
4229	_resetView: function (center, zoom) {
4230		setPosition(this._mapPane, new Point(0, 0));
4231
4232		var loading = !this._loaded;
4233		this._loaded = true;
4234		zoom = this._limitZoom(zoom);
4235
4236		this.fire('viewprereset');
4237
4238		var zoomChanged = this._zoom !== zoom;
4239		this
4240			._moveStart(zoomChanged, false)
4241			._move(center, zoom)
4242			._moveEnd(zoomChanged);
4243
4244		// @event viewreset: Event
4245		// Fired when the map needs to redraw its content (this usually happens
4246		// on map zoom or load). Very useful for creating custom overlays.
4247		this.fire('viewreset');
4248
4249		// @event load: Event
4250		// Fired when the map is initialized (when its center and zoom are set
4251		// for the first time).
4252		if (loading) {
4253			this.fire('load');
4254		}
4255	},
4256
4257	_moveStart: function (zoomChanged, noMoveStart) {
4258		// @event zoomstart: Event
4259		// Fired when the map zoom is about to change (e.g. before zoom animation).
4260		// @event movestart: Event
4261		// Fired when the view of the map starts changing (e.g. user starts dragging the map).
4262		if (zoomChanged) {
4263			this.fire('zoomstart');
4264		}
4265		if (!noMoveStart) {
4266			this.fire('movestart');
4267		}
4268		return this;
4269	},
4270
4271	_move: function (center, zoom, data) {
4272		if (zoom === undefined) {
4273			zoom = this._zoom;
4274		}
4275		var zoomChanged = this._zoom !== zoom;
4276
4277		this._zoom = zoom;
4278		this._lastCenter = center;
4279		this._pixelOrigin = this._getNewPixelOrigin(center);
4280
4281		// @event zoom: Event
4282		// Fired repeatedly during any change in zoom level, including zoom
4283		// and fly animations.
4284		if (zoomChanged || (data && data.pinch)) {	// Always fire 'zoom' if pinching because #3530
4285			this.fire('zoom', data);
4286		}
4287
4288		// @event move: Event
4289		// Fired repeatedly during any movement of the map, including pan and
4290		// fly animations.
4291		return this.fire('move', data);
4292	},
4293
4294	_moveEnd: function (zoomChanged) {
4295		// @event zoomend: Event
4296		// Fired when the map has changed, after any animations.
4297		if (zoomChanged) {
4298			this.fire('zoomend');
4299		}
4300
4301		// @event moveend: Event
4302		// Fired when the center of the map stops changing (e.g. user stopped
4303		// dragging the map).
4304		return this.fire('moveend');
4305	},
4306
4307	_stop: function () {
4308		cancelAnimFrame(this._flyToFrame);
4309		if (this._panAnim) {
4310			this._panAnim.stop();
4311		}
4312		return this;
4313	},
4314
4315	_rawPanBy: function (offset) {
4316		setPosition(this._mapPane, this._getMapPanePos().subtract(offset));
4317	},
4318
4319	_getZoomSpan: function () {
4320		return this.getMaxZoom() - this.getMinZoom();
4321	},
4322
4323	_panInsideMaxBounds: function () {
4324		if (!this._enforcingBounds) {
4325			this.panInsideBounds(this.options.maxBounds);
4326		}
4327	},
4328
4329	_checkIfLoaded: function () {
4330		if (!this._loaded) {
4331			throw new Error('Set map center and zoom first.');
4332		}
4333	},
4334
4335	// DOM event handling
4336
4337	// @section Interaction events
4338	_initEvents: function (remove$$1) {
4339		this._targets = {};
4340		this._targets[stamp(this._container)] = this;
4341
4342		var onOff = remove$$1 ? off : on;
4343
4344		// @event click: MouseEvent
4345		// Fired when the user clicks (or taps) the map.
4346		// @event dblclick: MouseEvent
4347		// Fired when the user double-clicks (or double-taps) the map.
4348		// @event mousedown: MouseEvent
4349		// Fired when the user pushes the mouse button on the map.
4350		// @event mouseup: MouseEvent
4351		// Fired when the user releases the mouse button on the map.
4352		// @event mouseover: MouseEvent
4353		// Fired when the mouse enters the map.
4354		// @event mouseout: MouseEvent
4355		// Fired when the mouse leaves the map.
4356		// @event mousemove: MouseEvent
4357		// Fired while the mouse moves over the map.
4358		// @event contextmenu: MouseEvent
4359		// Fired when the user pushes the right mouse button on the map, prevents
4360		// default browser context menu from showing if there are listeners on
4361		// this event. Also fired on mobile when the user holds a single touch
4362		// for a second (also called long press).
4363		// @event keypress: KeyboardEvent
4364		// Fired when the user presses a key from the keyboard while the map is focused.
4365		onOff(this._container, 'click dblclick mousedown mouseup ' +
4366			'mouseover mouseout mousemove contextmenu keypress', this._handleDOMEvent, this);
4367
4368		if (this.options.trackResize) {
4369			onOff(window, 'resize', this._onResize, this);
4370		}
4371
4372		if (any3d && this.options.transform3DLimit) {
4373			(remove$$1 ? this.off : this.on).call(this, 'moveend', this._onMoveEnd);
4374		}
4375	},
4376
4377	_onResize: function () {
4378		cancelAnimFrame(this._resizeRequest);
4379		this._resizeRequest = requestAnimFrame(
4380		        function () { this.invalidateSize({debounceMoveend: true}); }, this);
4381	},
4382
4383	_onScroll: function () {
4384		this._container.scrollTop  = 0;
4385		this._container.scrollLeft = 0;
4386	},
4387
4388	_onMoveEnd: function () {
4389		var pos = this._getMapPanePos();
4390		if (Math.max(Math.abs(pos.x), Math.abs(pos.y)) >= this.options.transform3DLimit) {
4391			// https://bugzilla.mozilla.org/show_bug.cgi?id=1203873 but Webkit also have
4392			// a pixel offset on very high values, see: http://jsfiddle.net/dg6r5hhb/
4393			this._resetView(this.getCenter(), this.getZoom());
4394		}
4395	},
4396
4397	_findEventTargets: function (e, type) {
4398		var targets = [],
4399		    target,
4400		    isHover = type === 'mouseout' || type === 'mouseover',
4401		    src = e.target || e.srcElement,
4402		    dragging = false;
4403
4404		while (src) {
4405			target = this._targets[stamp(src)];
4406			if (target && (type === 'click' || type === 'preclick') && !e._simulated && this._draggableMoved(target)) {
4407				// Prevent firing click after you just dragged an object.
4408				dragging = true;
4409				break;
4410			}
4411			if (target && target.listens(type, true)) {
4412				if (isHover && !isExternalTarget(src, e)) { break; }
4413				targets.push(target);
4414				if (isHover) { break; }
4415			}
4416			if (src === this._container) { break; }
4417			src = src.parentNode;
4418		}
4419		if (!targets.length && !dragging && !isHover && isExternalTarget(src, e)) {
4420			targets = [this];
4421		}
4422		return targets;
4423	},
4424
4425	_handleDOMEvent: function (e) {
4426		if (!this._loaded || skipped(e)) { return; }
4427
4428		var type = e.type;
4429
4430		if (type === 'mousedown' || type === 'keypress') {
4431			// prevents outline when clicking on keyboard-focusable element
4432			preventOutline(e.target || e.srcElement);
4433		}
4434
4435		this._fireDOMEvent(e, type);
4436	},
4437
4438	_mouseEvents: ['click', 'dblclick', 'mouseover', 'mouseout', 'contextmenu'],
4439
4440	_fireDOMEvent: function (e, type, targets) {
4441
4442		if (e.type === 'click') {
4443			// Fire a synthetic 'preclick' event which propagates up (mainly for closing popups).
4444			// @event preclick: MouseEvent
4445			// Fired before mouse click on the map (sometimes useful when you
4446			// want something to happen on click before any existing click
4447			// handlers start running).
4448			var synth = extend({}, e);
4449			synth.type = 'preclick';
4450			this._fireDOMEvent(synth, synth.type, targets);
4451		}
4452
4453		if (e._stopped) { return; }
4454
4455		// Find the layer the event is propagating from and its parents.
4456		targets = (targets || []).concat(this._findEventTargets(e, type));
4457
4458		if (!targets.length) { return; }
4459
4460		var target = targets[0];
4461		if (type === 'contextmenu' && target.listens(type, true)) {
4462			preventDefault(e);
4463		}
4464
4465		var data = {
4466			originalEvent: e
4467		};
4468
4469		if (e.type !== 'keypress') {
4470			var isMarker = target.getLatLng && (!target._radius || target._radius <= 10);
4471			data.containerPoint = isMarker ?
4472				this.latLngToContainerPoint(target.getLatLng()) : this.mouseEventToContainerPoint(e);
4473			data.layerPoint = this.containerPointToLayerPoint(data.containerPoint);
4474			data.latlng = isMarker ? target.getLatLng() : this.layerPointToLatLng(data.layerPoint);
4475		}
4476
4477		for (var i = 0; i < targets.length; i++) {
4478			targets[i].fire(type, data, true);
4479			if (data.originalEvent._stopped ||
4480				(targets[i].options.bubblingMouseEvents === false && indexOf(this._mouseEvents, type) !== -1)) { return; }
4481		}
4482	},
4483
4484	_draggableMoved: function (obj) {
4485		obj = obj.dragging && obj.dragging.enabled() ? obj : this;
4486		return (obj.dragging && obj.dragging.moved()) || (this.boxZoom && this.boxZoom.moved());
4487	},
4488
4489	_clearHandlers: function () {
4490		for (var i = 0, len = this._handlers.length; i < len; i++) {
4491			this._handlers[i].disable();
4492		}
4493	},
4494
4495	// @section Other Methods
4496
4497	// @method whenReady(fn: Function, context?: Object): this
4498	// Runs the given function `fn` when the map gets initialized with
4499	// a view (center and zoom) and at least one layer, or immediately
4500	// if it's already initialized, optionally passing a function context.
4501	whenReady: function (callback, context) {
4502		if (this._loaded) {
4503			callback.call(context || this, {target: this});
4504		} else {
4505			this.on('load', callback, context);
4506		}
4507		return this;
4508	},
4509
4510
4511	// private methods for getting map state
4512
4513	_getMapPanePos: function () {
4514		return getPosition(this._mapPane) || new Point(0, 0);
4515	},
4516
4517	_moved: function () {
4518		var pos = this._getMapPanePos();
4519		return pos && !pos.equals([0, 0]);
4520	},
4521
4522	_getTopLeftPoint: function (center, zoom) {
4523		var pixelOrigin = center && zoom !== undefined ?
4524			this._getNewPixelOrigin(center, zoom) :
4525			this.getPixelOrigin();
4526		return pixelOrigin.subtract(this._getMapPanePos());
4527	},
4528
4529	_getNewPixelOrigin: function (center, zoom) {
vendor: 6,570 bytes, lines 4530-4740
4530		var viewHalf = this.getSize()._divideBy(2);
4531		return this.project(center, zoom)._subtract(viewHalf)._add(this._getMapPanePos())._round();
4532	},
4533
4534	_latLngToNewLayerPoint: function (latlng, zoom, center) {
4535		var topLeft = this._getNewPixelOrigin(center, zoom);
4536		return this.project(latlng, zoom)._subtract(topLeft);
4537	},
4538
4539	_latLngBoundsToNewLayerBounds: function (latLngBounds, zoom, center) {
4540		var topLeft = this._getNewPixelOrigin(center, zoom);
4541		return toBounds([
4542			this.project(latLngBounds.getSouthWest(), zoom)._subtract(topLeft),
4543			this.project(latLngBounds.getNorthWest(), zoom)._subtract(topLeft),
4544			this.project(latLngBounds.getSouthEast(), zoom)._subtract(topLeft),
4545			this.project(latLngBounds.getNorthEast(), zoom)._subtract(topLeft)
4546		]);
4547	},
4548
4549	// layer point of the current center
4550	_getCenterLayerPoint: function () {
4551		return this.containerPointToLayerPoint(this.getSize()._divideBy(2));
4552	},
4553
4554	// offset of the specified place to the current center in pixels
4555	_getCenterOffset: function (latlng) {
4556		return this.latLngToLayerPoint(latlng).subtract(this._getCenterLayerPoint());
4557	},
4558
4559	// adjust center for view to get inside bounds
4560	_limitCenter: function (center, zoom, bounds) {
4561
4562		if (!bounds) { return center; }
4563
4564		var centerPoint = this.project(center, zoom),
4565		    viewHalf = this.getSize().divideBy(2),
4566		    viewBounds = new Bounds(centerPoint.subtract(viewHalf), centerPoint.add(viewHalf)),
4567		    offset = this._getBoundsOffset(viewBounds, bounds, zoom);
4568
4569		// If offset is less than a pixel, ignore.
4570		// This prevents unstable projections from getting into
4571		// an infinite loop of tiny offsets.
4572		if (offset.round().equals([0, 0])) {
4573			return center;
4574		}
4575
4576		return this.unproject(centerPoint.add(offset), zoom);
4577	},
4578
4579	// adjust offset for view to get inside bounds
4580	_limitOffset: function (offset, bounds) {
4581		if (!bounds) { return offset; }
4582
4583		var viewBounds = this.getPixelBounds(),
4584		    newBounds = new Bounds(viewBounds.min.add(offset), viewBounds.max.add(offset));
4585
4586		return offset.add(this._getBoundsOffset(newBounds, bounds));
4587	},
4588
4589	// returns offset needed for pxBounds to get inside maxBounds at a specified zoom
4590	_getBoundsOffset: function (pxBounds, maxBounds, zoom) {
4591		var projectedMaxBounds = toBounds(
4592		        this.project(maxBounds.getNorthEast(), zoom),
4593		        this.project(maxBounds.getSouthWest(), zoom)
4594		    ),
4595		    minOffset = projectedMaxBounds.min.subtract(pxBounds.min),
4596		    maxOffset = projectedMaxBounds.max.subtract(pxBounds.max),
4597
4598		    dx = this._rebound(minOffset.x, -maxOffset.x),
4599		    dy = this._rebound(minOffset.y, -maxOffset.y);
4600
4601		return new Point(dx, dy);
4602	},
4603
4604	_rebound: function (left, right) {
4605		return left + right > 0 ?
4606			Math.round(left - right) / 2 :
4607			Math.max(0, Math.ceil(left)) - Math.max(0, Math.floor(right));
4608	},
4609
4610	_limitZoom: function (zoom) {
4611		var min = this.getMinZoom(),
4612		    max = this.getMaxZoom(),
4613		    snap = any3d ? this.options.zoomSnap : 1;
4614		if (snap) {
4615			zoom = Math.round(zoom / snap) * snap;
4616		}
4617		return Math.max(min, Math.min(max, zoom));
4618	},
4619
4620	_onPanTransitionStep: function () {
4621		this.fire('move');
4622	},
4623
4624	_onPanTransitionEnd: function () {
4625		removeClass(this._mapPane, 'leaflet-pan-anim');
4626		this.fire('moveend');
4627	},
4628
4629	_tryAnimatedPan: function (center, options) {
4630		// difference between the new and current centers in pixels
4631		var offset = this._getCenterOffset(center)._trunc();
4632
4633		// don't animate too far unless animate: true specified in options
4634		if ((options && options.animate) !== true && !this.getSize().contains(offset)) { return false; }
4635
4636		this.panBy(offset, options);
4637
4638		return true;
4639	},
4640
4641	_createAnimProxy: function () {
4642
4643		var proxy = this._proxy = create$1('div', 'leaflet-proxy leaflet-zoom-animated');
4644		this._panes.mapPane.appendChild(proxy);
4645
4646		this.on('zoomanim', function (e) {
4647			var prop = TRANSFORM,
4648			    transform = this._proxy.style[prop];
4649
4650			setTransform(this._proxy, this.project(e.center, e.zoom), this.getZoomScale(e.zoom, 1));
4651
4652			// workaround for case when transform is the same and so transitionend event is not fired
4653			if (transform === this._proxy.style[prop] && this._animatingZoom) {
4654				this._onZoomTransitionEnd();
4655			}
4656		}, this);
4657
4658		this.on('load moveend', function () {
4659			var c = this.getCenter(),
4660			    z = this.getZoom();
4661			setTransform(this._proxy, this.project(c, z), this.getZoomScale(z, 1));
4662		}, this);
4663
4664		this._on('unload', this._destroyAnimProxy, this);
4665	},
4666
4667	_destroyAnimProxy: function () {
4668		remove(this._proxy);
4669		delete this._proxy;
4670	},
4671
4672	_catchTransitionEnd: function (e) {
4673		if (this._animatingZoom && e.propertyName.indexOf('transform') >= 0) {
4674			this._onZoomTransitionEnd();
4675		}
4676	},
4677
4678	_nothingToAnimate: function () {
4679		return !this._container.getElementsByClassName('leaflet-zoom-animated').length;
4680	},
4681
4682	_tryAnimatedZoom: function (center, zoom, options) {
4683
4684		if (this._animatingZoom) { return true; }
4685
4686		options = options || {};
4687
4688		// don't animate if disabled, not supported or zoom difference is too large
4689		if (!this._zoomAnimated || options.animate === false || this._nothingToAnimate() ||
4690		        Math.abs(zoom - this._zoom) > this.options.zoomAnimationThreshold) { return false; }
4691
4692		// offset is the pixel coords of the zoom origin relative to the current center
4693		var scale = this.getZoomScale(zoom),
4694		    offset = this._getCenterOffset(center)._divideBy(1 - 1 / scale);
4695
4696		// don't animate if the zoom origin isn't within one screen from the current center, unless forced
4697		if (options.animate !== true && !this.getSize().contains(offset)) { return false; }
4698
4699		requestAnimFrame(function () {
4700			this
4701			    ._moveStart(true, false)
4702			    ._animateZoom(center, zoom, true);
4703		}, this);
4704
4705		return true;
4706	},
4707
4708	_animateZoom: function (center, zoom, startAnim, noUpdate) {
4709		if (!this._mapPane) { return; }
4710
4711		if (startAnim) {
4712			this._animatingZoom = true;
4713
4714			// remember what center/zoom to set after animation
4715			this._animateToCenter = center;
4716			this._animateToZoom = zoom;
4717
4718			addClass(this._mapPane, 'leaflet-zoom-anim');
4719		}
4720
4721		// @event zoomanim: ZoomAnimEvent
4722		// Fired on every frame of a zoom animation
4723		this.fire('zoomanim', {
4724			center: center,
4725			zoom: zoom,
4726			noUpdate: noUpdate
4727		});
4728
4729		// Work around webkit not firing 'transitionend', see https://github.com/Leaflet/Leaflet/issues/3689, 2693
4730		setTimeout(bind(this._onZoomTransitionEnd, this), 250);
4731	},
4732
4733	_onZoomTransitionEnd: function () {
4734		if (!this._animatingZoom) { return; }
4735
4736		if (this._mapPane) {
4737			removeClass(this._mapPane, 'leaflet-zoom-anim');
4738		}
4739
4740		this._animatingZoom = false;
4741
4742		this._move(this._animateToCenter, this._animateToZoom);
4743
4744		// This anim frame should prevent an obscure iOS webkit tile loading race condition.
4745		requestAnimFrame(function () {
4746			this._moveEnd(true);
4747		}, this);
4748	}
4749});
4750
4751// @section
4752
4753// @factory L.map(id: String, options?: Map options)
4754// Instantiates a map object given the DOM ID of a `<div>` element
4755// and optionally an object literal with `Map options`.
4756//
4757// @alternative
4758// @factory L.map(el: HTMLElement, options?: Map options)
4759// Instantiates a map object given an instance of a `<div>` HTML element
4760// and optionally an object literal with `Map options`.
4761function createMap(id, options) {
4762	return new Map(id, options);
4763}
4764
4765/*
4766 * @class Control
4767 * @aka L.Control
4768 * @inherits Class
4769 *
4770 * L.Control is a base class for implementing map controls. Handles positioning.
4771 * All other controls extend from this class.
4772 */
4773
4774var Control = Class.extend({
4775	// @section
4776	// @aka Control options
4777	options: {
4778		// @option position: String = 'topright'
4779		// The position of the control (one of the map corners). Possible values are `'topleft'`,
4780		// `'topright'`, `'bottomleft'` or `'bottomright'`
4781		position: 'topright'
4782	},
4783
4784	initialize: function (options) {
4785		setOptions(this, options);
4786	},
4787
4788	/* @section
4789	 * Classes extending L.Control will inherit the following methods:
4790	 *
4791	 * @method getPosition: string
4792	 * Returns the position of the control.
4793	 */
4794	getPosition: function () {
4795		return this.options.position;
4796	},
4797
4798	// @method setPosition(position: string): this
4799	// Sets the position of the control.
4800	setPosition: function (position) {
4801		var map = this._map;
4802
4803		if (map) {
4804			map.removeControl(this);
4805		}
4806
4807		this.options.position = position;
4808
4809		if (map) {
4810			map.addControl(this);
4811		}
4812
4813		return this;
4814	},
4815
4816	// @method getContainer: HTMLElement
4817	// Returns the HTMLElement that contains the control.
4818	getContainer: function () {
4819		return this._container;
4820	},
4821
4822	// @method addTo(map: Map): this
4823	// Adds the control to the given map.
4824	addTo: function (map) {
4825		this.remove();
4826		this._map = map;
4827
4828		var container = this._container = this.onAdd(map),
4829		    pos = this.getPosition(),
4830		    corner = map._controlCorners[pos];
4831
4832		addClass(container, 'leaflet-control');
4833
4834		if (pos.indexOf('bottom') !== -1) {
4835			corner.insertBefore(container, corner.firstChild);
4836		} else {
4837			corner.appendChild(container);
4838		}
4839
4840		return this;
4841	},
4842
4843	// @method remove: this
4844	// Removes the control from the map it is currently active on.
4845	remove: function () {
4846		if (!this._map) {
4847			return this;
4848		}
4849
4850		remove(this._container);
4851
4852		if (this.onRemove) {
4853			this.onRemove(this._map);
4854		}
4855
4856		this._map = null;
4857
4858		return this;
4859	},
4860
4861	_refocusOnMap: function (e) {
4862		// if map exists and event is not a keyboard event
4863		if (this._map && e && e.screenX > 0 && e.screenY > 0) {
4864			this._map.getContainer().focus();
4865		}
4866	}
4867});
4868
vendor: 24,826 bytes, lines 4869-5784
4869var control = function (options) {
4870	return new Control(options);
4871};
4872
4873/* @section Extension methods
4874 * @uninheritable
4875 *
4876 * Every control should extend from `L.Control` and (re-)implement the following methods.
4877 *
4878 * @method onAdd(map: Map): HTMLElement
4879 * Should return the container DOM element for the control and add listeners on relevant map events. Called on [`control.addTo(map)`](#control-addTo).
4880 *
4881 * @method onRemove(map: Map)
4882 * Optional method. Should contain all clean up code that removes the listeners previously added in [`onAdd`](#control-onadd). Called on [`control.remove()`](#control-remove).
4883 */
4884
4885/* @namespace Map
4886 * @section Methods for Layers and Controls
4887 */
4888Map.include({
4889	// @method addControl(control: Control): this
4890	// Adds the given control to the map
4891	addControl: function (control) {
4892		control.addTo(this);
4893		return this;
4894	},
4895
4896	// @method removeControl(control: Control): this
4897	// Removes the given control from the map
4898	removeControl: function (control) {
4899		control.remove();
4900		return this;
4901	},
4902
4903	_initControlPos: function () {
4904		var corners = this._controlCorners = {},
4905		    l = 'leaflet-',
4906		    container = this._controlContainer =
4907		            create$1('div', l + 'control-container', this._container);
4908
4909		function createCorner(vSide, hSide) {
4910			var className = l + vSide + ' ' + l + hSide;
4911
4912			corners[vSide + hSide] = create$1('div', className, container);
4913		}
4914
4915		createCorner('top', 'left');
4916		createCorner('top', 'right');
4917		createCorner('bottom', 'left');
4918		createCorner('bottom', 'right');
4919	},
4920
4921	_clearControlPos: function () {
4922		for (var i in this._controlCorners) {
4923			remove(this._controlCorners[i]);
4924		}
4925		remove(this._controlContainer);
4926		delete this._controlCorners;
4927		delete this._controlContainer;
4928	}
4929});
4930
4931/*
4932 * @class Control.Layers
4933 * @aka L.Control.Layers
4934 * @inherits Control
4935 *
4936 * The layers control gives users the ability to switch between different base layers and switch overlays on/off (check out the [detailed example](http://leafletjs.com/examples/layers-control/)). Extends `Control`.
4937 *
4938 * @example
4939 *
4940 * ```js
4941 * var baseLayers = {
4942 * 	"Mapbox": mapbox,
4943 * 	"OpenStreetMap": osm
4944 * };
4945 *
4946 * var overlays = {
4947 * 	"Marker": marker,
4948 * 	"Roads": roadsLayer
4949 * };
4950 *
4951 * L.control.layers(baseLayers, overlays).addTo(map);
4952 * ```
4953 *
4954 * The `baseLayers` and `overlays` parameters are object literals with layer names as keys and `Layer` objects as values:
4955 *
4956 * ```js
4957 * {
4958 *     "<someName1>": layer1,
4959 *     "<someName2>": layer2
4960 * }
4961 * ```
4962 *
4963 * The layer names can contain HTML, which allows you to add additional styling to the items:
4964 *
4965 * ```js
4966 * {"<img src='my-layer-icon' /> <span class='my-layer-item'>My Layer</span>": myLayer}
4967 * ```
4968 */
4969
4970var Layers = Control.extend({
4971	// @section
4972	// @aka Control.Layers options
4973	options: {
4974		// @option collapsed: Boolean = true
4975		// If `true`, the control will be collapsed into an icon and expanded on mouse hover or touch.
4976		collapsed: true,
4977		position: 'topright',
4978
4979		// @option autoZIndex: Boolean = true
4980		// If `true`, the control will assign zIndexes in increasing order to all of its layers so that the order is preserved when switching them on/off.
4981		autoZIndex: true,
4982
4983		// @option hideSingleBase: Boolean = false
4984		// If `true`, the base layers in the control will be hidden when there is only one.
4985		hideSingleBase: false,
4986
4987		// @option sortLayers: Boolean = false
4988		// Whether to sort the layers. When `false`, layers will keep the order
4989		// in which they were added to the control.
4990		sortLayers: false,
4991
4992		// @option sortFunction: Function = *
4993		// A [compare function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)
4994		// that will be used for sorting the layers, when `sortLayers` is `true`.
4995		// The function receives both the `L.Layer` instances and their names, as in
4996		// `sortFunction(layerA, layerB, nameA, nameB)`.
4997		// By default, it sorts layers alphabetically by their name.
4998		sortFunction: function (layerA, layerB, nameA, nameB) {
4999			return nameA < nameB ? -1 : (nameB < nameA ? 1 : 0);
5000		}
5001	},
5002
5003	initialize: function (baseLayers, overlays, options) {
5004		setOptions(this, options);
5005
5006		this._layerControlInputs = [];
5007		this._layers = [];
5008		this._lastZIndex = 0;
5009		this._handlingClick = false;
5010
5011		for (var i in baseLayers) {
5012			this._addLayer(baseLayers[i], i);
5013		}
5014
5015		for (i in overlays) {
5016			this._addLayer(overlays[i], i, true);
5017		}
5018	},
5019
5020	onAdd: function (map) {
5021		this._initLayout();
5022		this._update();
5023
5024		this._map = map;
5025		map.on('zoomend', this._checkDisabledLayers, this);
5026
5027		for (var i = 0; i < this._layers.length; i++) {
5028			this._layers[i].layer.on('add remove', this._onLayerChange, this);
5029		}
5030
5031		return this._container;
5032	},
5033
5034	addTo: function (map) {
5035		Control.prototype.addTo.call(this, map);
5036		// Trigger expand after Layers Control has been inserted into DOM so that is now has an actual height.
5037		return this._expandIfNotCollapsed();
5038	},
5039
5040	onRemove: function () {
5041		this._map.off('zoomend', this._checkDisabledLayers, this);
5042
5043		for (var i = 0; i < this._layers.length; i++) {
5044			this._layers[i].layer.off('add remove', this._onLayerChange, this);
5045		}
5046	},
5047
5048	// @method addBaseLayer(layer: Layer, name: String): this
5049	// Adds a base layer (radio button entry) with the given name to the control.
5050	addBaseLayer: function (layer, name) {
5051		this._addLayer(layer, name);
5052		return (this._map) ? this._update() : this;
5053	},
5054
5055	// @method addOverlay(layer: Layer, name: String): this
5056	// Adds an overlay (checkbox entry) with the given name to the control.
5057	addOverlay: function (layer, name) {
5058		this._addLayer(layer, name, true);
5059		return (this._map) ? this._update() : this;
5060	},
5061
5062	// @method removeLayer(layer: Layer): this
5063	// Remove the given layer from the control.
5064	removeLayer: function (layer) {
5065		layer.off('add remove', this._onLayerChange, this);
5066
5067		var obj = this._getLayer(stamp(layer));
5068		if (obj) {
5069			this._layers.splice(this._layers.indexOf(obj), 1);
5070		}
5071		return (this._map) ? this._update() : this;
5072	},
5073
5074	// @method expand(): this
5075	// Expand the control container if collapsed.
5076	expand: function () {
5077		addClass(this._container, 'leaflet-control-layers-expanded');
5078		this._form.style.height = null;
5079		var acceptableHeight = this._map.getSize().y - (this._container.offsetTop + 50);
5080		if (acceptableHeight < this._form.clientHeight) {
5081			addClass(this._form, 'leaflet-control-layers-scrollbar');
5082			this._form.style.height = acceptableHeight + 'px';
5083		} else {
5084			removeClass(this._form, 'leaflet-control-layers-scrollbar');
5085		}
5086		this._checkDisabledLayers();
5087		return this;
5088	},
5089
5090	// @method collapse(): this
5091	// Collapse the control container if expanded.
5092	collapse: function () {
5093		removeClass(this._container, 'leaflet-control-layers-expanded');
5094		return this;
5095	},
5096
5097	_initLayout: function () {
5098		var className = 'leaflet-control-layers',
5099		    container = this._container = create$1('div', className),
5100		    collapsed = this.options.collapsed;
5101
5102		// makes this work on IE touch devices by stopping it from firing a mouseout event when the touch is released
5103		container.setAttribute('aria-haspopup', true);
5104
5105		disableClickPropagation(container);
5106		disableScrollPropagation(container);
5107
5108		var form = this._form = create$1('form', className + '-list');
5109
5110		if (collapsed) {
5111			this._map.on('click', this.collapse, this);
5112
5113			if (!android) {
5114				on(container, {
5115					mouseenter: this.expand,
5116					mouseleave: this.collapse
5117				}, this);
5118			}
5119		}
5120
5121		var link = this._layersLink = create$1('a', className + '-toggle', container);
5122		link.href = '#';
5123		link.title = 'Layers';
5124
5125		if (touch) {
5126			on(link, 'click', stop);
5127			on(link, 'click', this.expand, this);
5128		} else {
5129			on(link, 'focus', this.expand, this);
5130		}
5131
5132		if (!collapsed) {
5133			this.expand();
5134		}
5135
5136		this._baseLayersList = create$1('div', className + '-base', form);
5137		this._separator = create$1('div', className + '-separator', form);
5138		this._overlaysList = create$1('div', className + '-overlays', form);
5139
5140		container.appendChild(form);
5141	},
5142
5143	_getLayer: function (id) {
5144		for (var i = 0; i < this._layers.length; i++) {
5145
5146			if (this._layers[i] && stamp(this._layers[i].layer) === id) {
5147				return this._layers[i];
5148			}
5149		}
5150	},
5151
5152	_addLayer: function (layer, name, overlay) {
5153		if (this._map) {
5154			layer.on('add remove', this._onLayerChange, this);
5155		}
5156
5157		this._layers.push({
5158			layer: layer,
5159			name: name,
5160			overlay: overlay
5161		});
5162
5163		if (this.options.sortLayers) {
5164			this._layers.sort(bind(function (a, b) {
5165				return this.options.sortFunction(a.layer, b.layer, a.name, b.name);
5166			}, this));
5167		}
5168
5169		if (this.options.autoZIndex && layer.setZIndex) {
5170			this._lastZIndex++;
5171			layer.setZIndex(this._lastZIndex);
5172		}
5173
5174		this._expandIfNotCollapsed();
5175	},
5176
5177	_update: function () {
5178		if (!this._container) { return this; }
5179
5180		empty(this._baseLayersList);
5181		empty(this._overlaysList);
5182
5183		this._layerControlInputs = [];
5184		var baseLayersPresent, overlaysPresent, i, obj, baseLayersCount = 0;
5185
5186		for (i = 0; i < this._layers.length; i++) {
5187			obj = this._layers[i];
5188			this._addItem(obj);
5189			overlaysPresent = overlaysPresent || obj.overlay;
5190			baseLayersPresent = baseLayersPresent || !obj.overlay;
5191			baseLayersCount += !obj.overlay ? 1 : 0;
5192		}
5193
5194		// Hide base layers section if there's only one layer.
5195		if (this.options.hideSingleBase) {
5196			baseLayersPresent = baseLayersPresent && baseLayersCount > 1;
5197			this._baseLayersList.style.display = baseLayersPresent ? '' : 'none';
5198		}
5199
5200		this._separator.style.display = overlaysPresent && baseLayersPresent ? '' : 'none';
5201
5202		return this;
5203	},
5204
5205	_onLayerChange: function (e) {
5206		if (!this._handlingClick) {
5207			this._update();
5208		}
5209
5210		var obj = this._getLayer(stamp(e.target));
5211
5212		// @namespace Map
5213		// @section Layer events
5214		// @event baselayerchange: LayersControlEvent
5215		// Fired when the base layer is changed through the [layer control](#control-layers).
5216		// @event overlayadd: LayersControlEvent
5217		// Fired when an overlay is selected through the [layer control](#control-layers).
5218		// @event overlayremove: LayersControlEvent
5219		// Fired when an overlay is deselected through the [layer control](#control-layers).
5220		// @namespace Control.Layers
5221		var type = obj.overlay ?
5222			(e.type === 'add' ? 'overlayadd' : 'overlayremove') :
5223			(e.type === 'add' ? 'baselayerchange' : null);
5224
5225		if (type) {
5226			this._map.fire(type, obj);
5227		}
5228	},
5229
5230	// IE7 bugs out if you create a radio dynamically, so you have to do it this hacky way (see http://bit.ly/PqYLBe)
5231	_createRadioElement: function (name, checked) {
5232
5233		var radioHtml = '<input type="radio" class="leaflet-control-layers-selector" name="' +
5234				name + '"' + (checked ? ' checked="checked"' : '') + '/>';
5235
5236		var radioFragment = document.createElement('div');
5237		radioFragment.innerHTML = radioHtml;
5238
5239		return radioFragment.firstChild;
5240	},
5241
5242	_addItem: function (obj) {
5243		var label = document.createElement('label'),
5244		    checked = this._map.hasLayer(obj.layer),
5245		    input;
5246
5247		if (obj.overlay) {
5248			input = document.createElement('input');
5249			input.type = 'checkbox';
5250			input.className = 'leaflet-control-layers-selector';
5251			input.defaultChecked = checked;
5252		} else {
5253			input = this._createRadioElement('leaflet-base-layers', checked);
5254		}
5255
5256		this._layerControlInputs.push(input);
5257		input.layerId = stamp(obj.layer);
5258
5259		on(input, 'click', this._onInputClick, this);
5260
5261		var name = document.createElement('span');
5262		name.innerHTML = ' ' + obj.name;
5263
5264		// Helps from preventing layer control flicker when checkboxes are disabled
5265		// https://github.com/Leaflet/Leaflet/issues/2771
5266		var holder = document.createElement('div');
5267
5268		label.appendChild(holder);
5269		holder.appendChild(input);
5270		holder.appendChild(name);
5271
5272		var container = obj.overlay ? this._overlaysList : this._baseLayersList;
5273		container.appendChild(label);
5274
5275		this._checkDisabledLayers();
5276		return label;
5277	},
5278
5279	_onInputClick: function () {
5280		var inputs = this._layerControlInputs,
5281		    input, layer;
5282		var addedLayers = [],
5283		    removedLayers = [];
5284
5285		this._handlingClick = true;
5286
5287		for (var i = inputs.length - 1; i >= 0; i--) {
5288			input = inputs[i];
5289			layer = this._getLayer(input.layerId).layer;
5290
5291			if (input.checked) {
5292				addedLayers.push(layer);
5293			} else if (!input.checked) {
5294				removedLayers.push(layer);
5295			}
5296		}
5297
5298		// Bugfix issue 2318: Should remove all old layers before readding new ones
5299		for (i = 0; i < removedLayers.length; i++) {
5300			if (this._map.hasLayer(removedLayers[i])) {
5301				this._map.removeLayer(removedLayers[i]);
5302			}
5303		}
5304		for (i = 0; i < addedLayers.length; i++) {
5305			if (!this._map.hasLayer(addedLayers[i])) {
5306				this._map.addLayer(addedLayers[i]);
5307			}
5308		}
5309
5310		this._handlingClick = false;
5311
5312		this._refocusOnMap();
5313	},
5314
5315	_checkDisabledLayers: function () {
5316		var inputs = this._layerControlInputs,
5317		    input,
5318		    layer,
5319		    zoom = this._map.getZoom();
5320
5321		for (var i = inputs.length - 1; i >= 0; i--) {
5322			input = inputs[i];
5323			layer = this._getLayer(input.layerId).layer;
5324			input.disabled = (layer.options.minZoom !== undefined && zoom < layer.options.minZoom) ||
5325			                 (layer.options.maxZoom !== undefined && zoom > layer.options.maxZoom);
5326
5327		}
5328	},
5329
5330	_expandIfNotCollapsed: function () {
5331		if (this._map && !this.options.collapsed) {
5332			this.expand();
5333		}
5334		return this;
5335	},
5336
5337	_expand: function () {
5338		// Backward compatibility, remove me in 1.1.
5339		return this.expand();
5340	},
5341
5342	_collapse: function () {
5343		// Backward compatibility, remove me in 1.1.
5344		return this.collapse();
5345	}
5346
5347});
5348
5349
5350// @factory L.control.layers(baselayers?: Object, overlays?: Object, options?: Control.Layers options)
5351// Creates an attribution control with the given layers. Base layers will be switched with radio buttons, while overlays will be switched with checkboxes. Note that all base layers should be passed in the base layers object, but only one should be added to the map during map instantiation.
5352var layers = function (baseLayers, overlays, options) {
5353	return new Layers(baseLayers, overlays, options);
5354};
5355
5356/*
5357 * @class Control.Zoom
5358 * @aka L.Control.Zoom
5359 * @inherits Control
5360 *
5361 * A basic zoom control with two buttons (zoom in and zoom out). It is put on the map by default unless you set its [`zoomControl` option](#map-zoomcontrol) to `false`. Extends `Control`.
5362 */
5363
5364var Zoom = Control.extend({
5365	// @section
5366	// @aka Control.Zoom options
5367	options: {
5368		position: 'topleft',
5369
5370		// @option zoomInText: String = '+'
5371		// The text set on the 'zoom in' button.
5372		zoomInText: '+',
5373
5374		// @option zoomInTitle: String = 'Zoom in'
5375		// The title set on the 'zoom in' button.
5376		zoomInTitle: 'Zoom in',
5377
5378		// @option zoomOutText: String = '&#x2212;'
5379		// The text set on the 'zoom out' button.
5380		zoomOutText: '&#x2212;',
5381
5382		// @option zoomOutTitle: String = 'Zoom out'
5383		// The title set on the 'zoom out' button.
5384		zoomOutTitle: 'Zoom out'
5385	},
5386
5387	onAdd: function (map) {
5388		var zoomName = 'leaflet-control-zoom',
5389		    container = create$1('div', zoomName + ' leaflet-bar'),
5390		    options = this.options;
5391
5392		this._zoomInButton  = this._createButton(options.zoomInText, options.zoomInTitle,
5393		        zoomName + '-in',  container, this._zoomIn);
5394		this._zoomOutButton = this._createButton(options.zoomOutText, options.zoomOutTitle,
5395		        zoomName + '-out', container, this._zoomOut);
5396
5397		this._updateDisabled();
5398		map.on('zoomend zoomlevelschange', this._updateDisabled, this);
5399
5400		return container;
5401	},
5402
5403	onRemove: function (map) {
5404		map.off('zoomend zoomlevelschange', this._updateDisabled, this);
5405	},
5406
5407	disable: function () {
5408		this._disabled = true;
5409		this._updateDisabled();
5410		return this;
5411	},
5412
5413	enable: function () {
5414		this._disabled = false;
5415		this._updateDisabled();
5416		return this;
5417	},
5418
5419	_zoomIn: function (e) {
5420		if (!this._disabled && this._map._zoom < this._map.getMaxZoom()) {
5421			this._map.zoomIn(this._map.options.zoomDelta * (e.shiftKey ? 3 : 1));
5422		}
5423	},
5424
5425	_zoomOut: function (e) {
5426		if (!this._disabled && this._map._zoom > this._map.getMinZoom()) {
5427			this._map.zoomOut(this._map.options.zoomDelta * (e.shiftKey ? 3 : 1));
5428		}
5429	},
5430
5431	_createButton: function (html, title, className, container, fn) {
5432		var link = create$1('a', className, container);
5433		link.innerHTML = html;
5434		link.href = '#';
5435		link.title = title;
5436
5437		/*
5438		 * Will force screen readers like VoiceOver to read this as "Zoom in - button"
5439		 */
5440		link.setAttribute('role', 'button');
5441		link.setAttribute('aria-label', title);
5442
5443		disableClickPropagation(link);
5444		on(link, 'click', stop);
5445		on(link, 'click', fn, this);
5446		on(link, 'click', this._refocusOnMap, this);
5447
5448		return link;
5449	},
5450
5451	_updateDisabled: function () {
5452		var map = this._map,
5453		    className = 'leaflet-disabled';
5454
5455		removeClass(this._zoomInButton, className);
5456		removeClass(this._zoomOutButton, className);
5457
5458		if (this._disabled || map._zoom === map.getMinZoom()) {
5459			addClass(this._zoomOutButton, className);
5460		}
5461		if (this._disabled || map._zoom === map.getMaxZoom()) {
5462			addClass(this._zoomInButton, className);
5463		}
5464	}
5465});
5466
5467// @namespace Map
5468// @section Control options
5469// @option zoomControl: Boolean = true
5470// Whether a [zoom control](#control-zoom) is added to the map by default.
5471Map.mergeOptions({
5472	zoomControl: true
5473});
5474
5475Map.addInitHook(function () {
5476	if (this.options.zoomControl) {
5477		// @section Controls
5478		// @property zoomControl: Control.Zoom
5479		// The default zoom control (only available if the
5480		// [`zoomControl` option](#map-zoomcontrol) was `true` when creating the map).
5481		this.zoomControl = new Zoom();
5482		this.addControl(this.zoomControl);
5483	}
5484});
5485
5486// @namespace Control.Zoom
5487// @factory L.control.zoom(options: Control.Zoom options)
5488// Creates a zoom control
5489var zoom = function (options) {
5490	return new Zoom(options);
5491};
5492
5493/*
5494 * @class Control.Scale
5495 * @aka L.Control.Scale
5496 * @inherits Control
5497 *
5498 * A simple scale control that shows the scale of the current center of screen in metric (m/km) and imperial (mi/ft) systems. Extends `Control`.
5499 *
5500 * @example
5501 *
5502 * ```js
5503 * L.control.scale().addTo(map);
5504 * ```
5505 */
5506
5507var Scale = Control.extend({
5508	// @section
5509	// @aka Control.Scale options
5510	options: {
5511		position: 'bottomleft',
5512
5513		// @option maxWidth: Number = 100
5514		// Maximum width of the control in pixels. The width is set dynamically to show round values (e.g. 100, 200, 500).
5515		maxWidth: 100,
5516
5517		// @option metric: Boolean = True
5518		// Whether to show the metric scale line (m/km).
5519		metric: true,
5520
5521		// @option imperial: Boolean = True
5522		// Whether to show the imperial scale line (mi/ft).
5523		imperial: true
5524
5525		// @option updateWhenIdle: Boolean = false
5526		// If `true`, the control is updated on [`moveend`](#map-moveend), otherwise it's always up-to-date (updated on [`move`](#map-move)).
5527	},
5528
5529	onAdd: function (map) {
5530		var className = 'leaflet-control-scale',
5531		    container = create$1('div', className),
5532		    options = this.options;
5533
5534		this._addScales(options, className + '-line', container);
5535
5536		map.on(options.updateWhenIdle ? 'moveend' : 'move', this._update, this);
5537		map.whenReady(this._update, this);
5538
5539		return container;
5540	},
5541
5542	onRemove: function (map) {
5543		map.off(this.options.updateWhenIdle ? 'moveend' : 'move', this._update, this);
5544	},
5545
5546	_addScales: function (options, className, container) {
5547		if (options.metric) {
5548			this._mScale = create$1('div', className, container);
5549		}
5550		if (options.imperial) {
5551			this._iScale = create$1('div', className, container);
5552		}
5553	},
5554
5555	_update: function () {
5556		var map = this._map,
5557		    y = map.getSize().y / 2;
5558
5559		var maxMeters = map.distance(
5560			map.containerPointToLatLng([0, y]),
5561			map.containerPointToLatLng([this.options.maxWidth, y]));
5562
5563		this._updateScales(maxMeters);
5564	},
5565
5566	_updateScales: function (maxMeters) {
5567		if (this.options.metric && maxMeters) {
5568			this._updateMetric(maxMeters);
5569		}
5570		if (this.options.imperial && maxMeters) {
5571			this._updateImperial(maxMeters);
5572		}
5573	},
5574
5575	_updateMetric: function (maxMeters) {
5576		var meters = this._getRoundNum(maxMeters),
5577		    label = meters < 1000 ? meters + ' m' : (meters / 1000) + ' km';
5578
5579		this._updateScale(this._mScale, label, meters / maxMeters);
5580	},
5581
5582	_updateImperial: function (maxMeters) {
5583		var maxFeet = maxMeters * 3.2808399,
5584		    maxMiles, miles, feet;
5585
5586		if (maxFeet > 5280) {
5587			maxMiles = maxFeet / 5280;
5588			miles = this._getRoundNum(maxMiles);
5589			this._updateScale(this._iScale, miles + ' mi', miles / maxMiles);
5590
5591		} else {
5592			feet = this._getRoundNum(maxFeet);
5593			this._updateScale(this._iScale, feet + ' ft', feet / maxFeet);
5594		}
5595	},
5596
5597	_updateScale: function (scale, text, ratio) {
5598		scale.style.width = Math.round(this.options.maxWidth * ratio) + 'px';
5599		scale.innerHTML = text;
5600	},
5601
5602	_getRoundNum: function (num) {
5603		var pow10 = Math.pow(10, (Math.floor(num) + '').length - 1),
5604		    d = num / pow10;
5605
5606		d = d >= 10 ? 10 :
5607		    d >= 5 ? 5 :
5608		    d >= 3 ? 3 :
5609		    d >= 2 ? 2 : 1;
5610
5611		return pow10 * d;
5612	}
5613});
5614
5615
5616// @factory L.control.scale(options?: Control.Scale options)
5617// Creates an scale control with the given options.
5618var scale = function (options) {
5619	return new Scale(options);
5620};
5621
5622/*
5623 * @class Control.Attribution
5624 * @aka L.Control.Attribution
5625 * @inherits Control
5626 *
5627 * The attribution control allows you to display attribution data in a small text box on a map. It is put on the map by default unless you set its [`attributionControl` option](#map-attributioncontrol) to `false`, and it fetches attribution texts from layers with the [`getAttribution` method](#layer-getattribution) automatically. Extends Control.
5628 */
5629
5630var Attribution = Control.extend({
5631	// @section
5632	// @aka Control.Attribution options
5633	options: {
5634		position: 'bottomright',
5635
5636		// @option prefix: String = 'Leaflet'
5637		// The HTML text shown before the attributions. Pass `false` to disable.
5638		prefix: '<a href="http://leafletjs.com" title="A JS library for interactive maps">Leaflet</a>'
5639	},
5640
5641	initialize: function (options) {
5642		setOptions(this, options);
5643
5644		this._attributions = {};
5645	},
5646
5647	onAdd: function (map) {
5648		map.attributionControl = this;
5649		this._container = create$1('div', 'leaflet-control-attribution');
5650		disableClickPropagation(this._container);
5651
5652		// TODO ugly, refactor
5653		for (var i in map._layers) {
5654			if (map._layers[i].getAttribution) {
5655				this.addAttribution(map._layers[i].getAttribution());
5656			}
5657		}
5658
5659		this._update();
5660
5661		return this._container;
5662	},
5663
5664	// @method setPrefix(prefix: String): this
5665	// Sets the text before the attributions.
5666	setPrefix: function (prefix) {
5667		this.options.prefix = prefix;
5668		this._update();
5669		return this;
5670	},
5671
5672	// @method addAttribution(text: String): this
5673	// Adds an attribution text (e.g. `'Vector data &copy; Mapbox'`).
5674	addAttribution: function (text) {
5675		if (!text) { return this; }
5676
5677		if (!this._attributions[text]) {
5678			this._attributions[text] = 0;
5679		}
5680		this._attributions[text]++;
5681
5682		this._update();
5683
5684		return this;
5685	},
5686
5687	// @method removeAttribution(text: String): this
5688	// Removes an attribution text.
5689	removeAttribution: function (text) {
5690		if (!text) { return this; }
5691
5692		if (this._attributions[text]) {
5693			this._attributions[text]--;
5694			this._update();
5695		}
5696
5697		return this;
5698	},
5699
5700	_update: function () {
5701		if (!this._map) { return; }
5702
5703		var attribs = [];
5704
5705		for (var i in this._attributions) {
5706			if (this._attributions[i]) {
5707				attribs.push(i);
5708			}
5709		}
5710
5711		var prefixAndAttribs = [];
5712
5713		if (this.options.prefix) {
5714			prefixAndAttribs.push(this.options.prefix);
5715		}
5716		if (attribs.length) {
5717			prefixAndAttribs.push(attribs.join(', '));
5718		}
5719
5720		this._container.innerHTML = prefixAndAttribs.join(' | ');
5721	}
5722});
5723
5724// @namespace Map
5725// @section Control options
5726// @option attributionControl: Boolean = true
5727// Whether a [attribution control](#control-attribution) is added to the map by default.
5728Map.mergeOptions({
5729	attributionControl: true
5730});
5731
5732Map.addInitHook(function () {
5733	if (this.options.attributionControl) {
5734		new Attribution().addTo(this);
5735	}
5736});
5737
5738// @namespace Control.Attribution
5739// @factory L.control.attribution(options: Control.Attribution options)
5740// Creates an attribution control.
5741var attribution = function (options) {
5742	return new Attribution(options);
5743};
5744
5745Control.Layers = Layers;
5746Control.Zoom = Zoom;
5747Control.Scale = Scale;
5748Control.Attribution = Attribution;
5749
5750control.layers = layers;
5751control.zoom = zoom;
5752control.scale = scale;
5753control.attribution = attribution;
5754
5755/*
5756	L.Handler is a base class for handler classes that are used internally to inject
5757	interaction features like dragging to classes like Map and Marker.
5758*/
5759
5760// @class Handler
5761// @aka L.Handler
5762// Abstract class for map interaction handlers
5763
5764var Handler = Class.extend({
5765	initialize: function (map) {
5766		this._map = map;
5767	},
5768
5769	// @method enable(): this
5770	// Enables the handler
5771	enable: function () {
5772		if (this._enabled) { return this; }
5773
5774		this._enabled = true;
5775		this.addHooks();
5776		return this;
5777	},
5778
5779	// @method disable(): this
5780	// Disables the handler
5781	disable: function () {
5782		if (!this._enabled) { return this; }
5783
5784		this._enabled = false;
5785		this.removeHooks();
5786		return this;
5787	},
5788
5789	// @method enabled(): Boolean
5790	// Returns `true` if the handler is enabled
5791	enabled: function () {
5792		return !!this._enabled;
5793	}
5794
5795	// @section Extension methods
5796	// Classes inheriting from `Handler` must implement the two following methods:
5797	// @method addHooks()
5798	// Called when the handler is enabled, should add event hooks.
5799	// @method removeHooks()
5800	// Called when the handler is disabled, should remove the event hooks added previously.
5801});
5802
5803// @section There is static function which can be called without instantiating L.Handler:
5804// @function addTo(map: Map, name: String): this
5805// Adds a new Handler to the given map with the given name.
5806Handler.addTo = function (map, name) {
5807	map.addHandler(name, this);
5808	return this;
5809};
5810
5811var Mixin = {Events: Events};
5812
5813/*
5814 * @class Draggable
5815 * @aka L.Draggable
5816 * @inherits Evented
5817 *
5818 * A class for making DOM elements draggable (including touch support).
5819 * Used internally for map and marker dragging. Only works for elements
5820 * that were positioned with [`L.DomUtil.setPosition`](#domutil-setposition).
5821 *
5822 * @example
5823 * ```js
5824 * var draggable = new L.Draggable(elementToDrag);
5825 * draggable.enable();
5826 * ```
5827 */
5828
5829var START = touch ? 'touchstart mousedown' : 'mousedown';
5830var END = {
5831	mousedown: 'mouseup',
5832	touchstart: 'touchend',
5833	pointerdown: 'touchend',
5834	MSPointerDown: 'touchend'
5835};
5836var MOVE = {
5837	mousedown: 'mousemove',
5838	touchstart: 'touchmove',
5839	pointerdown: 'touchmove',
5840	MSPointerDown: 'touchmove'
5841};
5842
5843
5844var Draggable = Evented.extend({
5845
5846	options: {
5847		// @section
5848		// @aka Draggable options
5849		// @option clickTolerance: Number = 3
5850		// The max number of pixels a user can shift the mouse pointer during a click
5851		// for it to be considered a valid click (as opposed to a mouse drag).
5852		clickTolerance: 3
5853	},
5854
5855	// @constructor L.Draggable(el: HTMLElement, dragHandle?: HTMLElement, preventOutline?: Boolean, options?: Draggable options)
5856	// Creates a `Draggable` object for moving `el` when you start dragging the `dragHandle` element (equals `el` itself by default).
5857	initialize: function (element, dragStartTarget, preventOutline$$1, options) {
5858		setOptions(this, options);
5859
5860		this._element = element;
5861		this._dragStartTarget = dragStartTarget || element;
5862		this._preventOutline = preventOutline$$1;
5863	},
5864
5865	// @method enable()
5866	// Enables the dragging ability
5867	enable: function () {
5868		if (this._enabled) { return; }
5869
5870		on(this._dragStartTarget, START, this._onDown, this);
5871
5872		this._enabled = true;
5873	},
5874
5875	// @method disable()
5876	// Disables the dragging ability
5877	disable: function () {
5878		if (!this._enabled) { return; }
5879
5880		// If we're currently dragging this draggable,
5881		// disabling it counts as first ending the drag.
5882		if (Draggable._dragging === this) {
5883			this.finishDrag();
5884		}
5885
5886		off(this._dragStartTarget, START, this._onDown, this);
5887
5888		this._enabled = false;
5889		this._moved = false;
5890	},
5891
5892	_onDown: function (e) {
5893		// Ignore simulated events, since we handle both touch and
5894		// mouse explicitly; otherwise we risk getting duplicates of
5895		// touch events, see #4315.
5896		// Also ignore the event if disabled; this happens in IE11
5897		// under some circumstances, see #3666.
5898		if (e._simulated || !this._enabled) { return; }
5899
5900		this._moved = false;
5901
5902		if (hasClass(this._element, 'leaflet-zoom-anim')) { return; }
5903
5904		if (Draggable._dragging || e.shiftKey || ((e.which !== 1) && (e.button !== 1) && !e.touches)) { return; }
5905		Draggable._dragging = this;  // Prevent dragging multiple objects at once.
5906
5907		if (this._preventOutline) {
5908			preventOutline(this._element);
5909		}
5910
5911		disableImageDrag();
5912		disableTextSelection();
5913
5914		if (this._moving) { return; }
5915
5916		// @event down: Event
5917		// Fired when a drag is about to start.
5918		this.fire('down');
5919
5920		var first = e.touches ? e.touches[0] : e,
5921		    sizedParent = getSizedParentNode(this._element);
5922
5923		this._startPoint = new Point(first.clientX, first.clientY);
5924
5925		// Cache the scale, so that we can continuously compensate for it during drag (_onMove).
5926		this._parentScale = getScale(sizedParent);
5927
5928		on(document, MOVE[e.type], this._onMove, this);
5929		on(document, END[e.type], this._onUp, this);
5930	},
5931
5932	_onMove: function (e) {
5933		// Ignore simulated events, since we handle both touch and
5934		// mouse explicitly; otherwise we risk getting duplicates of
5935		// touch events, see #4315.
5936		// Also ignore the event if disabled; this happens in IE11
5937		// under some circumstances, see #3666.
5938		if (e._simulated || !this._enabled) { return; }
5939
5940		if (e.touches && e.touches.length > 1) {
5941			this._moved = true;
5942			return;
5943		}
5944
5945		var first = (e.touches && e.touches.length === 1 ? e.touches[0] : e),
5946		    offset = new Point(first.clientX, first.clientY)._subtract(this._startPoint);
5947
5948		if (!offset.x && !offset.y) { return; }
5949		if (Math.abs(offset.x) + Math.abs(offset.y) < this.options.clickTolerance) { return; }
5950
5951		// We assume that the parent container's position, border and scale do not change for the duration of the drag.
5952		// Therefore there is no need to account for the position and border (they are eliminated by the subtraction)
5953		// and we can use the cached value for the scale.
5954		offset.x /= this._parentScale.x;
5955		offset.y /= this._parentScale.y;
5956
5957		preventDefault(e);
5958
5959		if (!this._moved) {
5960			// @event dragstart: Event
5961			// Fired when a drag starts
5962			this.fire('dragstart');
5963
5964			this._moved = true;
5965			this._startPos = getPosition(this._element).subtract(offset);
5966
5967			addClass(document.body, 'leaflet-dragging');
5968
5969			this._lastTarget = e.target || e.srcElement;
5970			// IE and Edge do not give the <use> element, so fetch it
5971			// if necessary
5972			if ((window.SVGElementInstance) && (this._lastTarget instanceof SVGElementInstance)) {
5973				this._lastTarget = this._lastTarget.correspondingUseElement;
5974			}
5975			addClass(this._lastTarget, 'leaflet-drag-target');
5976		}
5977
5978		this._newPos = this._startPos.add(offset);
5979		this._moving = true;
5980
5981		cancelAnimFrame(this._animRequest);
5982		this._lastEvent = e;
5983		this._animRequest = requestAnimFrame(this._updatePosition, this, true);
5984	},
5985
5986	_updatePosition: function () {
5987		var e = {originalEvent: this._lastEvent};
5988
5989		// @event predrag: Event
5990		// Fired continuously during dragging *before* each corresponding
5991		// update of the element's position.
5992		this.fire('predrag', e);
5993		setPosition(this._element, this._newPos);
5994
5995		// @event drag: Event
5996		// Fired continuously during dragging.
5997		this.fire('drag', e);
5998	},
5999
6000	_onUp: function (e) {
6001		// Ignore simulated events, since we handle both touch and
6002		// mouse explicitly; otherwise we risk getting duplicates of
6003		// touch events, see #4315.
6004		// Also ignore the event if disabled; this happens in IE11
6005		// under some circumstances, see #3666.
6006		if (e._simulated || !this._enabled) { return; }
6007		this.finishDrag();
6008	},
6009
6010	finishDrag: function () {
6011		removeClass(document.body, 'leaflet-dragging');
6012
6013		if (this._lastTarget) {
6014			removeClass(this._lastTarget, 'leaflet-drag-target');
6015			this._lastTarget = null;
6016		}
6017
6018		for (var i in MOVE) {
6019			off(document, MOVE[i], this._onMove, this);
6020			off(document, END[i], this._onUp, this);
6021		}
6022
6023		enableImageDrag();
6024		enableTextSelection();
6025
6026		if (this._moved && this._moving) {
6027			// ensure drag is not fired after dragend
6028			cancelAnimFrame(this._animRequest);
6029
6030			// @event dragend: DragEndEvent
6031			// Fired when the drag ends.
6032			this.fire('dragend', {
6033				distance: this._newPos.distanceTo(this._startPos)
6034			});
6035		}
6036
6037		this._moving = false;
6038		Draggable._dragging = false;
6039	}
6040
6041});
6042
6043/*
6044 * @namespace LineUtil
6045 *
6046 * Various utility functions for polyline points processing, used by Leaflet internally to make polylines lightning-fast.
6047 */
6048
6049// Simplify polyline with vertex reduction and Douglas-Peucker simplification.
6050// Improves rendering performance dramatically by lessening the number of points to draw.
6051
6052// @function simplify(points: Point[], tolerance: Number): Point[]
6053// Dramatically reduces the number of points in a polyline while retaining
6054// its shape and returns a new array of simplified points, using the
6055// [Douglas-Peucker algorithm](http://en.wikipedia.org/wiki/Douglas-Peucker_algorithm).
6056// Used for a huge performance boost when processing/displaying Leaflet polylines for
6057// each zoom level and also reducing visual noise. tolerance affects the amount of
6058// simplification (lesser value means higher quality but slower and with more points).
6059// Also released as a separated micro-library [Simplify.js](http://mourner.github.com/simplify-js/).
6060function simplify(points, tolerance) {
6061	if (!tolerance || !points.length) {
6062		return points.slice();
6063	}
6064
6065	var sqTolerance = tolerance * tolerance;
6066
6067	    // stage 1: vertex reduction
6068	    points = _reducePoints(points, sqTolerance);
6069
6070	    // stage 2: Douglas-Peucker simplification
6071	    points = _simplifyDP(points, sqTolerance);
6072
6073	return points;
6074}
6075
6076// @function pointToSegmentDistance(p: Point, p1: Point, p2: Point): Number
6077// Returns the distance between point `p` and segment `p1` to `p2`.
6078function pointToSegmentDistance(p, p1, p2) {
6079	return Math.sqrt(_sqClosestPointOnSegment(p, p1, p2, true));
6080}
6081
6082// @function closestPointOnSegment(p: Point, p1: Point, p2: Point): Number
6083// Returns the closest point from a point `p` on a segment `p1` to `p2`.
6084function closestPointOnSegment(p, p1, p2) {
6085	return _sqClosestPointOnSegment(p, p1, p2);
6086}
6087
6088// Douglas-Peucker simplification, see http://en.wikipedia.org/wiki/Douglas-Peucker_algorithm
6089function _simplifyDP(points, sqTolerance) {
6090
6091	var len = points.length,
6092	    ArrayConstructor = typeof Uint8Array !== undefined + '' ? Uint8Array : Array,
6093	    markers = new ArrayConstructor(len);
6094
6095	    markers[0] = markers[len - 1] = 1;
6096
6097	_simplifyDPStep(points, markers, sqTolerance, 0, len - 1);
6098
6099	var i,
6100	    newPoints = [];
6101
6102	for (i = 0; i < len; i++) {
6103		if (markers[i]) {
6104			newPoints.push(points[i]);
6105		}
6106	}
6107
6108	return newPoints;
6109}
6110
6111function _simplifyDPStep(points, markers, sqTolerance, first, last) {
6112
6113	var maxSqDist = 0,
6114	index, i, sqDist;
6115
6116	for (i = first + 1; i <= last - 1; i++) {
6117		sqDist = _sqClosestPointOnSegment(points[i], points[first], points[last], true);
6118
6119		if (sqDist > maxSqDist) {
6120			index = i;
6121			maxSqDist = sqDist;
6122		}
6123	}
6124
6125	if (maxSqDist > sqTolerance) {
6126		markers[index] = 1;
6127
6128		_simplifyDPStep(points, markers, sqTolerance, first, index);
6129		_simplifyDPStep(points, markers, sqTolerance, index, last);
6130	}
6131}
6132
6133// reduce points that are too close to each other to a single point
6134function _reducePoints(points, sqTolerance) {
6135	var reducedPoints = [points[0]];
6136
6137	for (var i = 1, prev = 0, len = points.length; i < len; i++) {
6138		if (_sqDist(points[i], points[prev]) > sqTolerance) {
6139			reducedPoints.push(points[i]);
6140			prev = i;
6141		}
6142	}
6143	if (prev < len - 1) {
6144		reducedPoints.push(points[len - 1]);
6145	}
6146	return reducedPoints;
6147}
6148
6149var _lastCode;
6150
6151// @function clipSegment(a: Point, b: Point, bounds: Bounds, useLastCode?: Boolean, roun
vendor: 66,773 bytes, lines 6151-8662
6151d?: Boolean): Point[]|Boolean
6152// Clips the segment a to b by rectangular bounds with the
6153// [Cohen-Sutherland algorithm](https://en.wikipedia.org/wiki/Cohen%E2%80%93Sutherland_algorithm)
6154// (modifying the segment points directly!). Used by Leaflet to only show polyline
6155// points that are on the screen or near, increasing performance.
6156function clipSegment(a, b, bounds, useLastCode, round) {
6157	var codeA = useLastCode ? _lastCode : _getBitCode(a, bounds),
6158	    codeB = _getBitCode(b, bounds),
6159
6160	    codeOut, p, newCode;
6161
6162	    // save 2nd code to avoid calculating it on the next segment
6163	    _lastCode = codeB;
6164
6165	while (true) {
6166		// if a,b is inside the clip window (trivial accept)
6167		if (!(codeA | codeB)) {
6168			return [a, b];
6169		}
6170
6171		// if a,b is outside the clip window (trivial reject)
6172		if (codeA & codeB) {
6173			return false;
6174		}
6175
6176		// other cases
6177		codeOut = codeA || codeB;
6178		p = _getEdgeIntersection(a, b, codeOut, bounds, round);
6179		newCode = _getBitCode(p, bounds);
6180
6181		if (codeOut === codeA) {
6182			a = p;
6183			codeA = newCode;
6184		} else {
6185			b = p;
6186			codeB = newCode;
6187		}
6188	}
6189}
6190
6191function _getEdgeIntersection(a, b, code, bounds, round) {
6192	var dx = b.x - a.x,
6193	    dy = b.y - a.y,
6194	    min = bounds.min,
6195	    max = bounds.max,
6196	    x, y;
6197
6198	if (code & 8) { // top
6199		x = a.x + dx * (max.y - a.y) / dy;
6200		y = max.y;
6201
6202	} else if (code & 4) { // bottom
6203		x = a.x + dx * (min.y - a.y) / dy;
6204		y = min.y;
6205
6206	} else if (code & 2) { // right
6207		x = max.x;
6208		y = a.y + dy * (max.x - a.x) / dx;
6209
6210	} else if (code & 1) { // left
6211		x = min.x;
6212		y = a.y + dy * (min.x - a.x) / dx;
6213	}
6214
6215	return new Point(x, y, round);
6216}
6217
6218function _getBitCode(p, bounds) {
6219	var code = 0;
6220
6221	if (p.x < bounds.min.x) { // left
6222		code |= 1;
6223	} else if (p.x > bounds.max.x) { // right
6224		code |= 2;
6225	}
6226
6227	if (p.y < bounds.min.y) { // bottom
6228		code |= 4;
6229	} else if (p.y > bounds.max.y) { // top
6230		code |= 8;
6231	}
6232
6233	return code;
6234}
6235
6236// square distance (to avoid unnecessary Math.sqrt calls)
6237function _sqDist(p1, p2) {
6238	var dx = p2.x - p1.x,
6239	    dy = p2.y - p1.y;
6240	return dx * dx + dy * dy;
6241}
6242
6243// return closest point on segment or distance to that point
6244function _sqClosestPointOnSegment(p, p1, p2, sqDist) {
6245	var x = p1.x,
6246	    y = p1.y,
6247	    dx = p2.x - x,
6248	    dy = p2.y - y,
6249	    dot = dx * dx + dy * dy,
6250	    t;
6251
6252	if (dot > 0) {
6253		t = ((p.x - x) * dx + (p.y - y) * dy) / dot;
6254
6255		if (t > 1) {
6256			x = p2.x;
6257			y = p2.y;
6258		} else if (t > 0) {
6259			x += dx * t;
6260			y += dy * t;
6261		}
6262	}
6263
6264	dx = p.x - x;
6265	dy = p.y - y;
6266
6267	return sqDist ? dx * dx + dy * dy : new Point(x, y);
6268}
6269
6270
6271// @function isFlat(latlngs: LatLng[]): Boolean
6272// Returns true if `latlngs` is a flat array, false is nested.
6273function isFlat(latlngs) {
6274	return !isArray(latlngs[0]) || (typeof latlngs[0][0] !== 'object' && typeof latlngs[0][0] !== 'undefined');
6275}
6276
6277function _flat(latlngs) {
6278	console.warn('Deprecated use of _flat, please use L.LineUtil.isFlat instead.');
6279	return isFlat(latlngs);
6280}
6281
6282
6283var LineUtil = (Object.freeze || Object)({
6284	simplify: simplify,
6285	pointToSegmentDistance: pointToSegmentDistance,
6286	closestPointOnSegment: closestPointOnSegment,
6287	clipSegment: clipSegment,
6288	_getEdgeIntersection: _getEdgeIntersection,
6289	_getBitCode: _getBitCode,
6290	_sqClosestPointOnSegment: _sqClosestPointOnSegment,
6291	isFlat: isFlat,
6292	_flat: _flat
6293});
6294
6295/*
6296 * @namespace PolyUtil
6297 * Various utility functions for polygon geometries.
6298 */
6299
6300/* @function clipPolygon(points: Point[], bounds: Bounds, round?: Boolean): Point[]
6301 * Clips the polygon geometry defined by the given `points` by the given bounds (using the [Sutherland-Hodgman algorithm](https://en.wikipedia.org/wiki/Sutherland%E2%80%93Hodgman_algorithm)).
6302 * Used by Leaflet to only show polygon points that are on the screen or near, increasing
6303 * performance. Note that polygon points needs different algorithm for clipping
6304 * than polyline, so there's a separate method for it.
6305 */
6306function clipPolygon(points, bounds, round) {
6307	var clippedPoints,
6308	    edges = [1, 4, 2, 8],
6309	    i, j, k,
6310	    a, b,
6311	    len, edge, p;
6312
6313	for (i = 0, len = points.length; i < len; i++) {
6314		points[i]._code = _getBitCode(points[i], bounds);
6315	}
6316
6317	// for each edge (left, bottom, right, top)
6318	for (k = 0; k < 4; k++) {
6319		edge = edges[k];
6320		clippedPoints = [];
6321
6322		for (i = 0, len = points.length, j = len - 1; i < len; j = i++) {
6323			a = points[i];
6324			b = points[j];
6325
6326			// if a is inside the clip window
6327			if (!(a._code & edge)) {
6328				// if b is outside the clip window (a->b goes out of screen)
6329				if (b._code & edge) {
6330					p = _getEdgeIntersection(b, a, edge, bounds, round);
6331					p._code = _getBitCode(p, bounds);
6332					clippedPoints.push(p);
6333				}
6334				clippedPoints.push(a);
6335
6336			// else if b is inside the clip window (a->b enters the screen)
6337			} else if (!(b._code & edge)) {
6338				p = _getEdgeIntersection(b, a, edge, bounds, round);
6339				p._code = _getBitCode(p, bounds);
6340				clippedPoints.push(p);
6341			}
6342		}
6343		points = clippedPoints;
6344	}
6345
6346	return points;
6347}
6348
6349
6350var PolyUtil = (Object.freeze || Object)({
6351	clipPolygon: clipPolygon
6352});
6353
6354/*
6355 * @namespace Projection
6356 * @section
6357 * Leaflet comes with a set of already defined Projections out of the box:
6358 *
6359 * @projection L.Projection.LonLat
6360 *
6361 * Equirectangular, or Plate Carree projection — the most simple projection,
6362 * mostly used by GIS enthusiasts. Directly maps `x` as longitude, and `y` as
6363 * latitude. Also suitable for flat worlds, e.g. game maps. Used by the
6364 * `EPSG:4326` and `Simple` CRS.
6365 */
6366
6367var LonLat = {
6368	project: function (latlng) {
6369		return new Point(latlng.lng, latlng.lat);
6370	},
6371
6372	unproject: function (point) {
6373		return new LatLng(point.y, point.x);
6374	},
6375
6376	bounds: new Bounds([-180, -90], [180, 90])
6377};
6378
6379/*
6380 * @namespace Projection
6381 * @projection L.Projection.Mercator
6382 *
6383 * Elliptical Mercator projection — more complex than Spherical Mercator. Takes into account that Earth is a geoid, not a perfect sphere. Used by the EPSG:3395 CRS.
6384 */
6385
6386var Mercator = {
6387	R: 6378137,
6388	R_MINOR: 6356752.314245179,
6389
6390	bounds: new Bounds([-20037508.34279, -15496570.73972], [20037508.34279, 18764656.23138]),
6391
6392	project: function (latlng) {
6393		var d = Math.PI / 180,
6394		    r = this.R,
6395		    y = latlng.lat * d,
6396		    tmp = this.R_MINOR / r,
6397		    e = Math.sqrt(1 - tmp * tmp),
6398		    con = e * Math.sin(y);
6399
6400		var ts = Math.tan(Math.PI / 4 - y / 2) / Math.pow((1 - con) / (1 + con), e / 2);
6401		y = -r * Math.log(Math.max(ts, 1E-10));
6402
6403		return new Point(latlng.lng * d * r, y);
6404	},
6405
6406	unproject: function (point) {
6407		var d = 180 / Math.PI,
6408		    r = this.R,
6409		    tmp = this.R_MINOR / r,
6410		    e = Math.sqrt(1 - tmp * tmp),
6411		    ts = Math.exp(-point.y / r),
6412		    phi = Math.PI / 2 - 2 * Math.atan(ts);
6413
6414		for (var i = 0, dphi = 0.1, con; i < 15 && Math.abs(dphi) > 1e-7; i++) {
6415			con = e * Math.sin(phi);
6416			con = Math.pow((1 - con) / (1 + con), e / 2);
6417			dphi = Math.PI / 2 - 2 * Math.atan(ts * con) - phi;
6418			phi += dphi;
6419		}
6420
6421		return new LatLng(phi * d, point.x * d / r);
6422	}
6423};
6424
6425/*
6426 * @class Projection
6427
6428 * An object with methods for projecting geographical coordinates of the world onto
6429 * a flat surface (and back). See [Map projection](http://en.wikipedia.org/wiki/Map_projection).
6430
6431 * @property bounds: Bounds
6432 * The bounds (specified in CRS units) where the projection is valid
6433
6434 * @method project(latlng: LatLng): Point
6435 * Projects geographical coordinates into a 2D point.
6436 * Only accepts actual `L.LatLng` instances, not arrays.
6437
6438 * @method unproject(point: Point): LatLng
6439 * The inverse of `project`. Projects a 2D point into a geographical location.
6440 * Only accepts actual `L.Point` instances, not arrays.
6441
6442 * Note that the projection instances do not inherit from Leafet's `Class` object,
6443 * and can't be instantiated. Also, new classes can't inherit from them,
6444 * and methods can't be added to them with the `include` function.
6445
6446 */
6447
6448
6449
6450
6451var index = (Object.freeze || Object)({
6452	LonLat: LonLat,
6453	Mercator: Mercator,
6454	SphericalMercator: SphericalMercator
6455});
6456
6457/*
6458 * @namespace CRS
6459 * @crs L.CRS.EPSG3395
6460 *
6461 * Rarely used by some commercial tile providers. Uses Elliptical Mercator projection.
6462 */
6463var EPSG3395 = extend({}, Earth, {
6464	code: 'EPSG:3395',
6465	projection: Mercator,
6466
6467	transformation: (function () {
6468		var scale = 0.5 / (Math.PI * Mercator.R);
6469		return toTransformation(scale, 0.5, -scale, 0.5);
6470	}())
6471});
6472
6473/*
6474 * @namespace CRS
6475 * @crs L.CRS.EPSG4326
6476 *
6477 * A common CRS among GIS enthusiasts. Uses simple Equirectangular projection.
6478 *
6479 * Leaflet 1.0.x complies with the [TMS coordinate scheme for EPSG:4326](https://wiki.osgeo.org/wiki/Tile_Map_Service_Specification#global-geodetic),
6480 * which is a breaking change from 0.7.x behaviour.  If you are using a `TileLayer`
6481 * with this CRS, ensure that there are two 256x256 pixel tiles covering the
6482 * whole earth at zoom level zero, and that the tile coordinate origin is (-180,+90),
6483 * or (-180,-90) for `TileLayer`s with [the `tms` option](#tilelayer-tms) set.
6484 */
6485
6486var EPSG4326 = extend({}, Earth, {
6487	code: 'EPSG:4326',
6488	projection: LonLat,
6489	transformation: toTransformation(1 / 180, 1, -1 / 180, 0.5)
6490});
6491
6492/*
6493 * @namespace CRS
6494 * @crs L.CRS.Simple
6495 *
6496 * A simple CRS that maps longitude and latitude into `x` and `y` directly.
6497 * May be used for maps of flat surfaces (e.g. game maps). Note that the `y`
6498 * axis should still be inverted (going from bottom to top). `distance()` returns
6499 * simple euclidean distance.
6500 */
6501
6502var Simple = extend({}, CRS, {
6503	projection: LonLat,
6504	transformation: toTransformation(1, 0, -1, 0),
6505
6506	scale: function (zoom) {
6507		return Math.pow(2, zoom);
6508	},
6509
6510	zoom: function (scale) {
6511		return Math.log(scale) / Math.LN2;
6512	},
6513
6514	distance: function (latlng1, latlng2) {
6515		var dx = latlng2.lng - latlng1.lng,
6516		    dy = latlng2.lat - latlng1.lat;
6517
6518		return Math.sqrt(dx * dx + dy * dy);
6519	},
6520
6521	infinite: true
6522});
6523
6524CRS.Earth = Earth;
6525CRS.EPSG3395 = EPSG3395;
6526CRS.EPSG3857 = EPSG3857;
6527CRS.EPSG900913 = EPSG900913;
6528CRS.EPSG4326 = EPSG4326;
6529CRS.Simple = Simple;
6530
6531/*
6532 * @class Layer
6533 * @inherits Evented
6534 * @aka L.Layer
6535 * @aka ILayer
6536 *
6537 * A set of methods from the Layer base class that all Leaflet layers use.
6538 * Inherits all methods, options and events from `L.Evented`.
6539 *
6540 * @example
6541 *
6542 * ```js
6543 * var layer = L.Marker(latlng).addTo(map);
6544 * layer.addTo(map);
6545 * layer.remove();
6546 * ```
6547 *
6548 * @event add: Event
6549 * Fired after the layer is added to a map
6550 *
6551 * @event remove: Event
6552 * Fired after the layer is removed from a map
6553 */
6554
6555
6556var Layer = Evented.extend({
6557
6558	// Classes extending `L.Layer` will inherit the following options:
6559	options: {
6560		// @option pane: String = 'overlayPane'
6561		// By default the layer will be added to the map's [overlay pane](#map-overlaypane). Overriding this option will cause the layer to be placed on another pane by default.
6562		pane: 'overlayPane',
6563
6564		// @option attribution: String = null
6565		// String to be shown in the attribution control, describes the layer data, e.g. "© Mapbox".
6566		attribution: null,
6567
6568		bubblingMouseEvents: true
6569	},
6570
6571	/* @section
6572	 * Classes extending `L.Layer` will inherit the following methods:
6573	 *
6574	 * @method addTo(map: Map|LayerGroup): this
6575	 * Adds the layer to the given map or layer group.
6576	 */
6577	addTo: function (map) {
6578		map.addLayer(this);
6579		return this;
6580	},
6581
6582	// @method remove: this
6583	// Removes the layer from the map it is currently active on.
6584	remove: function () {
6585		return this.removeFrom(this._map || this._mapToAdd);
6586	},
6587
6588	// @method removeFrom(map: Map): this
6589	// Removes the layer from the given map
6590	removeFrom: function (obj) {
6591		if (obj) {
6592			obj.removeLayer(this);
6593		}
6594		return this;
6595	},
6596
6597	// @method getPane(name? : String): HTMLElement
6598	// Returns the `HTMLElement` representing the named pane on the map. If `name` is omitted, returns the pane for this layer.
6599	getPane: function (name) {
6600		return this._map.getPane(name ? (this.options[name] || name) : this.options.pane);
6601	},
6602
6603	addInteractiveTarget: function (targetEl) {
6604		this._map._targets[stamp(targetEl)] = this;
6605		return this;
6606	},
6607
6608	removeInteractiveTarget: function (targetEl) {
6609		delete this._map._targets[stamp(targetEl)];
6610		return this;
6611	},
6612
6613	// @method getAttribution: String
6614	// Used by the `attribution control`, returns the [attribution option](#gridlayer-attribution).
6615	getAttribution: function () {
6616		return this.options.attribution;
6617	},
6618
6619	_layerAdd: function (e) {
6620		var map = e.target;
6621
6622		// check in case layer gets added and then removed before the map is ready
6623		if (!map.hasLayer(this)) { return; }
6624
6625		this._map = map;
6626		this._zoomAnimated = map._zoomAnimated;
6627
6628		if (this.getEvents) {
6629			var events = this.getEvents();
6630			map.on(events, this);
6631			this.once('remove', function () {
6632				map.off(events, this);
6633			}, this);
6634		}
6635
6636		this.onAdd(map);
6637
6638		if (this.getAttribution && map.attributionControl) {
6639			map.attributionControl.addAttribution(this.getAttribution());
6640		}
6641
6642		this.fire('add');
6643		map.fire('layeradd', {layer: this});
6644	}
6645});
6646
6647/* @section Extension methods
6648 * @uninheritable
6649 *
6650 * Every layer should extend from `L.Layer` and (re-)implement the following methods.
6651 *
6652 * @method onAdd(map: Map): this
6653 * Should contain code that creates DOM elements for the layer, adds them to `map panes` where they should belong and puts listeners on relevant map events. Called on [`map.addLayer(layer)`](#map-addlayer).
6654 *
6655 * @method onRemove(map: Map): this
6656 * Should contain all clean up code that removes the layer's elements from the DOM and removes listeners previously added in [`onAdd`](#layer-onadd). Called on [`map.removeLayer(layer)`](#map-removelayer).
6657 *
6658 * @method getEvents(): Object
6659 * This optional method should return an object like `{ viewreset: this._reset }` for [`addEventListener`](#evented-addeventlistener). The event handlers in this object will be automatically added and removed from the map with your layer.
6660 *
6661 * @method getAttribution(): String
6662 * This optional method should return a string containing HTML to be shown on the `Attribution control` whenever the layer is visible.
6663 *
6664 * @method beforeAdd(map: Map): this
6665 * Optional method. Called on [`map.addLayer(layer)`](#map-addlayer), before the layer is added to the map, before events are initialized, without waiting until the map is in a usable state. Use for early initialization only.
6666 */
6667
6668
6669/* @namespace Map
6670 * @section Layer events
6671 *
6672 * @event layeradd: LayerEvent
6673 * Fired when a new layer is added to the map.
6674 *
6675 * @event layerremove: LayerEvent
6676 * Fired when some layer is removed from the map
6677 *
6678 * @section Methods for Layers and Controls
6679 */
6680Map.include({
6681	// @method addLayer(layer: Layer): this
6682	// Adds the given layer to the map
6683	addLayer: function (layer) {
6684		if (!layer._layerAdd) {
6685			throw new Error('The provided object is not a Layer.');
6686		}
6687
6688		var id = stamp(layer);
6689		if (this._layers[id]) { return this; }
6690		this._layers[id] = layer;
6691
6692		layer._mapToAdd = this;
6693
6694		if (layer.beforeAdd) {
6695			layer.beforeAdd(this);
6696		}
6697
6698		this.whenReady(layer._layerAdd, layer);
6699
6700		return this;
6701	},
6702
6703	// @method removeLayer(layer: Layer): this
6704	// Removes the given layer from the map.
6705	removeLayer: function (layer) {
6706		var id = stamp(layer);
6707
6708		if (!this._layers[id]) { return this; }
6709
6710		if (this._loaded) {
6711			layer.onRemove(this);
6712		}
6713
6714		if (layer.getAttribution && this.attributionControl) {
6715			this.attributionControl.removeAttribution(layer.getAttribution());
6716		}
6717
6718		delete this._layers[id];
6719
6720		if (this._loaded) {
6721			this.fire('layerremove', {layer: layer});
6722			layer.fire('remove');
6723		}
6724
6725		layer._map = layer._mapToAdd = null;
6726
6727		return this;
6728	},
6729
6730	// @method hasLayer(layer: Layer): Boolean
6731	// Returns `true` if the given layer is currently added to the map
6732	hasLayer: function (layer) {
6733		return !!layer && (stamp(layer) in this._layers);
6734	},
6735
6736	/* @method eachLayer(fn: Function, context?: Object): this
6737	 * Iterates over the layers of the map, optionally specifying context of the iterator function.
6738	 * ```
6739	 * map.eachLayer(function(layer){
6740	 *     layer.bindPopup('Hello');
6741	 * });
6742	 * ```
6743	 */
6744	eachLayer: function (method, context) {
6745		for (var i in this._layers) {
6746			method.call(context, this._layers[i]);
6747		}
6748		return this;
6749	},
6750
6751	_addLayers: function (layers) {
6752		layers = layers ? (isArray(layers) ? layers : [layers]) : [];
6753
6754		for (var i = 0, len = layers.length; i < len; i++) {
6755			this.addLayer(layers[i]);
6756		}
6757	},
6758
6759	_addZoomLimit: function (layer) {
6760		if (isNaN(layer.options.maxZoom) || !isNaN(layer.options.minZoom)) {
6761			this._zoomBoundLayers[stamp(layer)] = layer;
6762			this._updateZoomLevels();
6763		}
6764	},
6765
6766	_removeZoomLimit: function (layer) {
6767		var id = stamp(layer);
6768
6769		if (this._zoomBoundLayers[id]) {
6770			delete this._zoomBoundLayers[id];
6771			this._updateZoomLevels();
6772		}
6773	},
6774
6775	_updateZoomLevels: function () {
6776		var minZoom = Infinity,
6777		    maxZoom = -Infinity,
6778		    oldZoomSpan = this._getZoomSpan();
6779
6780		for (var i in this._zoomBoundLayers) {
6781			var options = this._zoomBoundLayers[i].options;
6782
6783			minZoom = options.minZoom === undefined ? minZoom : Math.min(minZoom, options.minZoom);
6784			maxZoom = options.maxZoom === undefined ? maxZoom : Math.max(maxZoom, options.maxZoom);
6785		}
6786
6787		this._layersMaxZoom = maxZoom === -Infinity ? undefined : maxZoom;
6788		this._layersMinZoom = minZoom === Infinity ? undefined : minZoom;
6789
6790		// @section Map state change events
6791		// @event zoomlevelschange: Event
6792		// Fired when the number of zoomlevels on the map is changed due
6793		// to adding or removing a layer.
6794		if (oldZoomSpan !== this._getZoomSpan()) {
6795			this.fire('zoomlevelschange');
6796		}
6797
6798		if (this.options.maxZoom === undefined && this._layersMaxZoom && this.getZoom() > this._layersMaxZoom) {
6799			this.setZoom(this._layersMaxZoom);
6800		}
6801		if (this.options.minZoom === undefined && this._layersMinZoom && this.getZoom() < this._layersMinZoom) {
6802			this.setZoom(this._layersMinZoom);
6803		}
6804	}
6805});
6806
6807/*
6808 * @class LayerGroup
6809 * @aka L.LayerGroup
6810 * @inherits Layer
6811 *
6812 * Used to group several layers and handle them as one. If you add it to the map,
6813 * any layers added or removed from the group will be added/removed on the map as
6814 * well. Extends `Layer`.
6815 *
6816 * @example
6817 *
6818 * ```js
6819 * L.layerGroup([marker1, marker2])
6820 * 	.addLayer(polyline)
6821 * 	.addTo(map);
6822 * ```
6823 */
6824
6825var LayerGroup = Layer.extend({
6826
6827	initialize: function (layers, options) {
6828		setOptions(this, options);
6829
6830		this._layers = {};
6831
6832		var i, len;
6833
6834		if (layers) {
6835			for (i = 0, len = layers.length; i < len; i++) {
6836				this.addLayer(layers[i]);
6837			}
6838		}
6839	},
6840
6841	// @method addLayer(layer: Layer): this
6842	// Adds the given layer to the group.
6843	addLayer: function (layer) {
6844		var id = this.getLayerId(layer);
6845
6846		this._layers[id] = layer;
6847
6848		if (this._map) {
6849			this._map.addLayer(layer);
6850		}
6851
6852		return this;
6853	},
6854
6855	// @method removeLayer(layer: Layer): this
6856	// Removes the given layer from the group.
6857	// @alternative
6858	// @method removeLayer(id: Number): this
6859	// Removes the layer with the given internal ID from the group.
6860	removeLayer: function (layer) {
6861		var id = layer in this._layers ? layer : this.getLayerId(layer);
6862
6863		if (this._map && this._layers[id]) {
6864			this._map.removeLayer(this._layers[id]);
6865		}
6866
6867		delete this._layers[id];
6868
6869		return this;
6870	},
6871
6872	// @method hasLayer(layer: Layer): Boolean
6873	// Returns `true` if the given layer is currently added to the group.
6874	// @alternative
6875	// @method hasLayer(id: Number): Boolean
6876	// Returns `true` if the given internal ID is currently added to the group.
6877	hasLayer: function (layer) {
6878		return !!layer && (layer in this._layers || this.getLayerId(layer) in this._layers);
6879	},
6880
6881	// @method clearLayers(): this
6882	// Removes all the layers from the group.
6883	clearLayers: function () {
6884		return this.eachLayer(this.removeLayer, this);
6885	},
6886
6887	// @method invoke(methodName: String, …): this
6888	// Calls `methodName` on every layer contained in this group, passing any
6889	// additional parameters. Has no effect if the layers contained do not
6890	// implement `methodName`.
6891	invoke: function (methodName) {
6892		var args = Array.prototype.slice.call(arguments, 1),
6893		    i, layer;
6894
6895		for (i in this._layers) {
6896			layer = this._layers[i];
6897
6898			if (layer[methodName]) {
6899				layer[methodName].apply(layer, args);
6900			}
6901		}
6902
6903		return this;
6904	},
6905
6906	onAdd: function (map) {
6907		this.eachLayer(map.addLayer, map);
6908	},
6909
6910	onRemove: function (map) {
6911		this.eachLayer(map.removeLayer, map);
6912	},
6913
6914	// @method eachLayer(fn: Function, context?: Object): this
6915	// Iterates over the layers of the group, optionally specifying context of the iterator function.
6916	// ```js
6917	// group.eachLayer(function (layer) {
6918	// 	layer.bindPopup('Hello');
6919	// });
6920	// ```
6921	eachLayer: function (method, context) {
6922		for (var i in this._layers) {
6923			method.call(context, this._layers[i]);
6924		}
6925		return this;
6926	},
6927
6928	// @method getLayer(id: Number): Layer
6929	// Returns the layer with the given internal ID.
6930	getLayer: function (id) {
6931		return this._layers[id];
6932	},
6933
6934	// @method getLayers(): Layer[]
6935	// Returns an array of all the layers added to the group.
6936	getLayers: function () {
6937		var layers = [];
6938		this.eachLayer(layers.push, layers);
6939		return layers;
6940	},
6941
6942	// @method setZIndex(zIndex: Number): this
6943	// Calls `setZIndex` on every layer contained in this group, passing the z-index.
6944	setZIndex: function (zIndex) {
6945		return this.invoke('setZIndex', zIndex);
6946	},
6947
6948	// @method getLayerId(layer: Layer): Number
6949	// Returns the internal ID for a layer
6950	getLayerId: function (layer) {
6951		return stamp(layer);
6952	}
6953});
6954
6955
6956// @factory L.layerGroup(layers?: Layer[], options?: Object)
6957// Create a layer group, optionally given an initial set of layers and an `options` object.
6958var layerGroup = function (layers, options) {
6959	return new LayerGroup(layers, options);
6960};
6961
6962/*
6963 * @class FeatureGroup
6964 * @aka L.FeatureGroup
6965 * @inherits LayerGroup
6966 *
6967 * Extended `LayerGroup` that makes it easier to do the same thing to all its member layers:
6968 *  * [`bindPopup`](#layer-bindpopup) binds a popup to all of the layers at once (likewise with [`bindTooltip`](#layer-bindtooltip))
6969 *  * Events are propagated to the `FeatureGroup`, so if the group has an event
6970 * handler, it will handle events from any of the layers. This includes mouse events
6971 * and custom events.
6972 *  * Has `layeradd` and `layerremove` events
6973 *
6974 * @example
6975 *
6976 * ```js
6977 * L.featureGroup([marker1, marker2, polyline])
6978 * 	.bindPopup('Hello world!')
6979 * 	.on('click', function() { alert('Clicked on a member of the group!'); })
6980 * 	.addTo(map);
6981 * ```
6982 */
6983
6984var FeatureGroup = LayerGroup.extend({
6985
6986	addLayer: function (layer) {
6987		if (this.hasLayer(layer)) {
6988			return this;
6989		}
6990
6991		layer.addEventParent(this);
6992
6993		LayerGroup.prototype.addLayer.call(this, layer);
6994
6995		// @event layeradd: LayerEvent
6996		// Fired when a layer is added to this `FeatureGroup`
6997		return this.fire('layeradd', {layer: layer});
6998	},
6999
7000	removeLayer: function (layer) {
7001		if (!this.hasLayer(layer)) {
7002			return this;
7003		}
7004		if (layer in this._layers) {
7005			layer = this._layers[layer];
7006		}
7007
7008		layer.removeEventParent(this);
7009
7010		LayerGroup.prototype.removeLayer.call(this, layer);
7011
7012		// @event layerremove: LayerEvent
7013		// Fired when a layer is removed from this `FeatureGroup`
7014		return this.fire('layerremove', {layer: layer});
7015	},
7016
7017	// @method setStyle(style: Path options): this
7018	// Sets the given path options to each layer of the group that has a `setStyle` method.
7019	setStyle: function (style) {
7020		return this.invoke('setStyle', style);
7021	},
7022
7023	// @method bringToFront(): this
7024	// Brings the layer group to the top of all other layers
7025	bringToFront: function () {
7026		return this.invoke('bringToFront');
7027	},
7028
7029	// @method bringToBack(): this
7030	// Brings the layer group to the back of all other layers
7031	bringToBack: function () {
7032		return this.invoke('bringToBack');
7033	},
7034
7035	// @method getBounds(): LatLngBounds
7036	// Returns the LatLngBounds of the Feature Group (created from bounds and coordinates of its children).
7037	getBounds: function () {
7038		var bounds = new LatLngBounds();
7039
7040		for (var id in this._layers) {
7041			var layer = this._layers[id];
7042			bounds.extend(layer.getBounds ? layer.getBounds() : layer.getLatLng());
7043		}
7044		return bounds;
7045	}
7046});
7047
7048// @factory L.featureGroup(layers: Layer[])
7049// Create a feature group, optionally given an initial set of layers.
7050var featureGroup = function (layers) {
7051	return new FeatureGroup(layers);
7052};
7053
7054/*
7055 * @class Icon
7056 * @aka L.Icon
7057 *
7058 * Represents an icon to provide when creating a marker.
7059 *
7060 * @example
7061 *
7062 * ```js
7063 * var myIcon = L.icon({
7064 *     iconUrl: 'my-icon.png',
7065 *     iconRetinaUrl: '[email protected]',
7066 *     iconSize: [38, 95],
7067 *     iconAnchor: [22, 94],
7068 *     popupAnchor: [-3, -76],
7069 *     shadowUrl: 'my-icon-shadow.png',
7070 *     shadowRetinaUrl: '[email protected]',
7071 *     shadowSize: [68, 95],
7072 *     shadowAnchor: [22, 94]
7073 * });
7074 *
7075 * L.marker([50.505, 30.57], {icon: myIcon}).addTo(map);
7076 * ```
7077 *
7078 * `L.Icon.Default` extends `L.Icon` and is the blue icon Leaflet uses for markers by default.
7079 *
7080 */
7081
7082var Icon = Class.extend({
7083
7084	/* @section
7085	 * @aka Icon options
7086	 *
7087	 * @option iconUrl: String = null
7088	 * **(required)** The URL to the icon image (absolute or relative to your script path).
7089	 *
7090	 * @option iconRetinaUrl: String = null
7091	 * The URL to a retina sized version of the icon image (absolute or relative to your
7092	 * script path). Used for Retina screen devices.
7093	 *
7094	 * @option iconSize: Point = null
7095	 * Size of the icon image in pixels.
7096	 *
7097	 * @option iconAnchor: Point = null
7098	 * The coordinates of the "tip" of the icon (relative to its top left corner). The icon
7099	 * will be aligned so that this point is at the marker's geographical location. Centered
7100	 * by default if size is specified, also can be set in CSS with negative margins.
7101	 *
7102	 * @option popupAnchor: Point = [0, 0]
7103	 * The coordinates of the point from which popups will "open", relative to the icon anchor.
7104	 *
7105	 * @option tooltipAnchor: Point = [0, 0]
7106	 * The coordinates of the point from which tooltips will "open", relative to the icon anchor.
7107	 *
7108	 * @option shadowUrl: String = null
7109	 * The URL to the icon shadow image. If not specified, no shadow image will be created.
7110	 *
7111	 * @option shadowRetinaUrl: String = null
7112	 *
7113	 * @option shadowSize: Point = null
7114	 * Size of the shadow image in pixels.
7115	 *
7116	 * @option shadowAnchor: Point = null
7117	 * The coordinates of the "tip" of the shadow (relative to its top left corner) (the same
7118	 * as iconAnchor if not specified).
7119	 *
7120	 * @option className: String = ''
7121	 * A custom class name to assign to both icon and shadow images. Empty by default.
7122	 */
7123
7124	options: {
7125		popupAnchor: [0, 0],
7126		tooltipAnchor: [0, 0]
7127	},
7128
7129	initialize: function (options) {
7130		setOptions(this, options);
7131	},
7132
7133	// @method createIcon(oldIcon?: HTMLElement): HTMLElement
7134	// Called internally when the icon has to be shown, returns a `<img>` HTML element
7135	// styled according to the options.
7136	createIcon: function (oldIcon) {
7137		return this._createIcon('icon', oldIcon);
7138	},
7139
7140	// @method createShadow(oldIcon?: HTMLElement): HTMLElement
7141	// As `createIcon`, but for the shadow beneath it.
7142	createShadow: function (oldIcon) {
7143		return this._createIcon('shadow', oldIcon);
7144	},
7145
7146	_createIcon: function (name, oldIcon) {
7147		var src = this._getIconUrl(name);
7148
7149		if (!src) {
7150			if (name === 'icon') {
7151				throw new Error('iconUrl not set in Icon options (see the docs).');
7152			}
7153			return null;
7154		}
7155
7156		var img = this._createImg(src, oldIcon && oldIcon.tagName === 'IMG' ? oldIcon : null);
7157		this._setIconStyles(img, name);
7158
7159		return img;
7160	},
7161
7162	_setIconStyles: function (img, name) {
7163		var options = this.options;
7164		var sizeOption = options[name + 'Size'];
7165
7166		if (typeof sizeOption === 'number') {
7167			sizeOption = [sizeOption, sizeOption];
7168		}
7169
7170		var size = toPoint(sizeOption),
7171		    anchor = toPoint(name === 'shadow' && options.shadowAnchor || options.iconAnchor ||
7172		            size && size.divideBy(2, true));
7173
7174		img.className = 'leaflet-marker-' + name + ' ' + (options.className || '');
7175
7176		if (anchor) {
7177			img.style.marginLeft = (-anchor.x) + 'px';
7178			img.style.marginTop  = (-anchor.y) + 'px';
7179		}
7180
7181		if (size) {
7182			img.style.width  = size.x + 'px';
7183			img.style.height = size.y + 'px';
7184		}
7185	},
7186
7187	_createImg: function (src, el) {
7188		el = el || document.createElement('img');
7189		el.src = src;
7190		return el;
7191	},
7192
7193	_getIconUrl: function (name) {
7194		return retina && this.options[name + 'RetinaUrl'] || this.options[name + 'Url'];
7195	}
7196});
7197
7198
7199// @factory L.icon(options: Icon options)
7200// Creates an icon instance with the given options.
7201function icon(options) {
7202	return new Icon(options);
7203}
7204
7205/*
7206 * @miniclass Icon.Default (Icon)
7207 * @aka L.Icon.Default
7208 * @section
7209 *
7210 * A trivial subclass of `Icon`, represents the icon to use in `Marker`s when
7211 * no icon is specified. Points to the blue marker image distributed with Leaflet
7212 * releases.
7213 *
7214 * In order to customize the default icon, just change the properties of `L.Icon.Default.prototype.options`
7215 * (which is a set of `Icon options`).
7216 *
7217 * If you want to _completely_ replace the default icon, override the
7218 * `L.Marker.prototype.options.icon` with your own icon instead.
7219 */
7220
7221var IconDefault = Icon.extend({
7222
7223	options: {
7224		iconUrl:       'marker-icon.png',
7225		iconRetinaUrl: 'marker-icon-2x.png',
7226		shadowUrl:     'marker-shadow.png',
7227		iconSize:    [25, 41],
7228		iconAnchor:  [12, 41],
7229		popupAnchor: [1, -34],
7230		tooltipAnchor: [16, -28],
7231		shadowSize:  [41, 41]
7232	},
7233
7234	_getIconUrl: function (name) {
7235		if (!IconDefault.imagePath) {	// Deprecated, backwards-compatibility only
7236			IconDefault.imagePath = this._detectIconPath();
7237		}
7238
7239		// @option imagePath: String
7240		// `Icon.Default` will try to auto-detect the location of the
7241		// blue icon images. If you are placing these images in a non-standard
7242		// way, set this option to point to the right path.
7243		return (this.options.imagePath || IconDefault.imagePath) + Icon.prototype._getIconUrl.call(this, name);
7244	},
7245
7246	_detectIconPath: function () {
7247		var el = create$1('div',  'leaflet-default-icon-path', document.body);
7248		var path = getStyle(el, 'background-image') ||
7249		           getStyle(el, 'backgroundImage');	// IE8
7250
7251		document.body.removeChild(el);
7252
7253		if (path === null || path.indexOf('url') !== 0) {
7254			path = '';
7255		} else {
7256			path = path.replace(/^url\(["']?/, '').replace(/marker-icon\.png["']?\)$/, '');
7257		}
7258
7259		return path;
7260	}
7261});
7262
7263/*
7264 * L.Handler.MarkerDrag is used internally by L.Marker to make the markers draggable.
7265 */
7266
7267
7268/* @namespace Marker
7269 * @section Interaction handlers
7270 *
7271 * Interaction handlers are properties of a marker instance that allow you to control interaction behavior in runtime, enabling or disabling certain features such as dragging (see `Handler` methods). Example:
7272 *
7273 * ```js
7274 * marker.dragging.disable();
7275 * ```
7276 *
7277 * @property dragging: Handler
7278 * Marker dragging handler (by both mouse and touch). Only valid when the marker is on the map (Otherwise set [`marker.options.draggable`](#marker-draggable)).
7279 */
7280
7281var MarkerDrag = Handler.extend({
7282	initialize: function (marker) {
7283		this._marker = marker;
7284	},
7285
7286	addHooks: function () {
7287		var icon = this._marker._icon;
7288
7289		if (!this._draggable) {
7290			this._draggable = new Draggable(icon, icon, true);
7291		}
7292
7293		this._draggable.on({
7294			dragstart: this._onDragStart,
7295			predrag: this._onPreDrag,
7296			drag: this._onDrag,
7297			dragend: this._onDragEnd
7298		}, this).enable();
7299
7300		addClass(icon, 'leaflet-marker-draggable');
7301	},
7302
7303	removeHooks: function () {
7304		this._draggable.off({
7305			dragstart: this._onDragStart,
7306			predrag: this._onPreDrag,
7307			drag: this._onDrag,
7308			dragend: this._onDragEnd
7309		}, this).disable();
7310
7311		if (this._marker._icon) {
7312			removeClass(this._marker._icon, 'leaflet-marker-draggable');
7313		}
7314	},
7315
7316	moved: function () {
7317		return this._draggable && this._draggable._moved;
7318	},
7319
7320	_adjustPan: function (e) {
7321		var marker = this._marker,
7322		    map = marker._map,
7323		    speed = this._marker.options.autoPanSpeed,
7324		    padding = this._marker.options.autoPanPadding,
7325		    iconPos = getPosition(marker._icon),
7326		    bounds = map.getPixelBounds(),
7327		    origin = map.getPixelOrigin();
7328
7329		var panBounds = toBounds(
7330			bounds.min._subtract(origin).add(padding),
7331			bounds.max._subtract(origin).subtract(padding)
7332		);
7333
7334		if (!panBounds.contains(iconPos)) {
7335			// Compute incremental movement
7336			var movement = toPoint(
7337				(Math.max(panBounds.max.x, iconPos.x) - panBounds.max.x) / (bounds.max.x - panBounds.max.x) -
7338				(Math.min(panBounds.min.x, iconPos.x) - panBounds.min.x) / (bounds.min.x - panBounds.min.x),
7339
7340				(Math.max(panBounds.max.y, iconPos.y) - panBounds.max.y) / (bounds.max.y - panBounds.max.y) -
7341				(Math.min(panBounds.min.y, iconPos.y) - panBounds.min.y) / (bounds.min.y - panBounds.min.y)
7342			).multiplyBy(speed);
7343
7344			map.panBy(movement, {animate: false});
7345
7346			this._draggable._newPos._add(movement);
7347			this._draggable._startPos._add(movement);
7348
7349			setPosition(marker._icon, this._draggable._newPos);
7350			this._onDrag(e);
7351
7352			this._panRequest = requestAnimFrame(this._adjustPan.bind(this, e));
7353		}
7354	},
7355
7356	_onDragStart: function () {
7357		// @section Dragging events
7358		// @event dragstart: Event
7359		// Fired when the user starts dragging the marker.
7360
7361		// @event movestart: Event
7362		// Fired when the marker starts moving (because of dragging).
7363
7364		this._oldLatLng = this._marker.getLatLng();
7365		this._marker
7366		    .closePopup()
7367		    .fire('movestart')
7368		    .fire('dragstart');
7369	},
7370
7371	_onPreDrag: function (e) {
7372		if (this._marker.options.autoPan) {
7373			cancelAnimFrame(this._panRequest);
7374			this._panRequest = requestAnimFrame(this._adjustPan.bind(this, e));
7375		}
7376	},
7377
7378	_onDrag: function (e) {
7379		var marker = this._marker,
7380		    shadow = marker._shadow,
7381		    iconPos = getPosition(marker._icon),
7382		    latlng = marker._map.layerPointToLatLng(iconPos);
7383
7384		// update shadow position
7385		if (shadow) {
7386			setPosition(shadow, iconPos);
7387		}
7388
7389		marker._latlng = latlng;
7390		e.latlng = latlng;
7391		e.oldLatLng = this._oldLatLng;
7392
7393		// @event drag: Event
7394		// Fired repeatedly while the user drags the marker.
7395		marker
7396		    .fire('move', e)
7397		    .fire('drag', e);
7398	},
7399
7400	_onDragEnd: function (e) {
7401		// @event dragend: DragEndEvent
7402		// Fired when the user stops dragging the marker.
7403
7404		 cancelAnimFrame(this._panRequest);
7405
7406		// @event moveend: Event
7407		// Fired when the marker stops moving (because of dragging).
7408		delete this._oldLatLng;
7409		this._marker
7410		    .fire('moveend')
7411		    .fire('dragend', e);
7412	}
7413});
7414
7415/*
7416 * @class Marker
7417 * @inherits Interactive layer
7418 * @aka L.Marker
7419 * L.Marker is used to display clickable/draggable icons on the map. Extends `Layer`.
7420 *
7421 * @example
7422 *
7423 * ```js
7424 * L.marker([50.5, 30.5]).addTo(map);
7425 * ```
7426 */
7427
7428var Marker = Layer.extend({
7429
7430	// @section
7431	// @aka Marker options
7432	options: {
7433		// @option icon: Icon = *
7434		// Icon instance to use for rendering the marker.
7435		// See [Icon documentation](#L.Icon) for details on how to customize the marker icon.
7436		// If not specified, a common instance of `L.Icon.Default` is used.
7437		icon: new IconDefault(),
7438
7439		// Option inherited from "Interactive layer" abstract class
7440		interactive: true,
7441
7442		// @option keyboard: Boolean = true
7443		// Whether the marker can be tabbed to with a keyboard and clicked by pressing enter.
7444		keyboard: true,
7445
7446		// @option title: String = ''
7447		// Text for the browser tooltip that appear on marker hover (no tooltip by default).
7448		title: '',
7449
7450		// @option alt: String = ''
7451		// Text for the `alt` attribute of the icon image (useful for accessibility).
7452		alt: '',
7453
7454		// @option zIndexOffset: Number = 0
7455		// By default, marker images zIndex is set automatically based on its latitude. Use this option if you want to put the marker on top of all others (or below), specifying a high value like `1000` (or high negative value, respectively).
7456		zIndexOffset: 0,
7457
7458		// @option opacity: Number = 1.0
7459		// The opacity of the marker.
7460		opacity: 1,
7461
7462		// @option riseOnHover: Boolean = false
7463		// If `true`, the marker will get on top of others when you hover the mouse over it.
7464		riseOnHover: false,
7465
7466		// @option riseOffset: Number = 250
7467		// The z-index offset used for the `riseOnHover` feature.
7468		riseOffset: 250,
7469
7470		// @option pane: String = 'markerPane'
7471		// `Map pane` where the markers icon will be added.
7472		pane: 'markerPane',
7473
7474		// @option bubblingMouseEvents: Boolean = false
7475		// When `true`, a mouse event on this marker will trigger the same event on the map
7476		// (unless [`L.DomEvent.stopPropagation`](#domevent-stoppropagation) is used).
7477		bubblingMouseEvents: false,
7478
7479		// @section Draggable marker options
7480		// @option draggable: Boolean = false
7481		// Whether the marker is draggable with mouse/touch or not.
7482		draggable: false,
7483
7484		// @option autoPan: Boolean = false
7485		// Whether to pan the map when dragging this marker near its edge or not.
7486		autoPan: false,
7487
7488		// @option autoPanPadding: Point = Point(50, 50)
7489		// Distance (in pixels to the left/right and to the top/bottom) of the
7490		// map edge to start panning the map.
7491		autoPanPadding: [50, 50],
7492
7493		// @option autoPanSpeed: Number = 10
7494		// Number of pixels the map should pan by.
7495		autoPanSpeed: 10
7496	},
7497
7498	/* @section
7499	 *
7500	 * In addition to [shared layer methods](#Layer) like `addTo()` and `remove()` and [popup methods](#Popup) like bindPopup() you can also use the following methods:
7501	 */
7502
7503	initialize: function (latlng, options) {
7504		setOptions(this, options);
7505		this._latlng = toLatLng(latlng);
7506	},
7507
7508	onAdd: function (map) {
7509		this._zoomAnimated = this._zoomAnimated && map.options.markerZoomAnimation;
7510
7511		if (this._zoomAnimated) {
7512			map.on('zoomanim', this._animateZoom, this);
7513		}
7514
7515		this._initIcon();
7516		this.update();
7517	},
7518
7519	onRemove: function (map) {
7520		if (this.dragging && this.dragging.enabled()) {
7521			this.options.draggable = true;
7522			this.dragging.removeHooks();
7523		}
7524		delete this.dragging;
7525
7526		if (this._zoomAnimated) {
7527			map.off('zoomanim', this._animateZoom, this);
7528		}
7529
7530		this._removeIcon();
7531		this._removeShadow();
7532	},
7533
7534	getEvents: function () {
7535		return {
7536			zoom: this.update,
7537			viewreset: this.update
7538		};
7539	},
7540
7541	// @method getLatLng: LatLng
7542	// Returns the current geographical position of the marker.
7543	getLatLng: function () {
7544		return this._latlng;
7545	},
7546
7547	// @method setLatLng(latlng: LatLng): this
7548	// Changes the marker position to the given point.
7549	setLatLng: function (latlng) {
7550		var oldLatLng = this._latlng;
7551		this._latlng = toLatLng(latlng);
7552		this.update();
7553
7554		// @event move: Event
7555		// Fired when the marker is moved via [`setLatLng`](#marker-setlatlng) or by [dragging](#marker-dragging). Old and new coordinates are included in event arguments as `oldLatLng`, `latlng`.
7556		return this.fire('move', {oldLatLng: oldLatLng, latlng: this._latlng});
7557	},
7558
7559	// @method setZIndexOffset(offset: Number): this
7560	// Changes the [zIndex offset](#marker-zindexoffset) of the marker.
7561	setZIndexOffset: function (offset) {
7562		this.options.zIndexOffset = offset;
7563		return this.update();
7564	},
7565
7566	// @method setIcon(icon: Icon): this
7567	// Changes the marker icon.
7568	setIcon: function (icon) {
7569
7570		this.options.icon = icon;
7571
7572		if (this._map) {
7573			this._initIcon();
7574			this.update();
7575		}
7576
7577		if (this._popup) {
7578			this.bindPopup(this._popup, this._popup.options);
7579		}
7580
7581		return this;
7582	},
7583
7584	getElement: function () {
7585		return this._icon;
7586	},
7587
7588	update: function () {
7589
7590		if (this._icon && this._map) {
7591			var pos = this._map.latLngToLayerPoint(this._latlng).round();
7592			this._setPos(pos);
7593		}
7594
7595		return this;
7596	},
7597
7598	_initIcon: function () {
7599		var options = this.options,
7600		    classToAdd = 'leaflet-zoom-' + (this._zoomAnimated ? 'animated' : 'hide');
7601
7602		var icon = options.icon.createIcon(this._icon),
7603		    addIcon = false;
7604
7605		// if we're not reusing the icon, remove the old one and init new one
7606		if (icon !== this._icon) {
7607			if (this._icon) {
7608				this._removeIcon();
7609			}
7610			addIcon = true;
7611
7612			if (options.title) {
7613				icon.title = options.title;
7614			}
7615
7616			if (icon.tagName === 'IMG') {
7617				icon.alt = options.alt || '';
7618			}
7619		}
7620
7621		addClass(icon, classToAdd);
7622
7623		if (options.keyboard) {
7624			icon.tabIndex = '0';
7625		}
7626
7627		this._icon = icon;
7628
7629		if (options.riseOnHover) {
7630			this.on({
7631				mouseover: this._bringToFront,
7632				mouseout: this._resetZIndex
7633			});
7634		}
7635
7636		var newShadow = options.icon.createShadow(this._shadow),
7637		    addShadow = false;
7638
7639		if (newShadow !== this._shadow) {
7640			this._removeShadow();
7641			addShadow = true;
7642		}
7643
7644		if (newShadow) {
7645			addClass(newShadow, classToAdd);
7646			newShadow.alt = '';
7647		}
7648		this._shadow = newShadow;
7649
7650
7651		if (options.opacity < 1) {
7652			this._updateOpacity();
7653		}
7654
7655
7656		if (addIcon) {
7657			this.getPane().appendChild(this._icon);
7658		}
7659		this._initInteraction();
7660		if (newShadow && addShadow) {
7661			this.getPane('shadowPane').appendChild(this._shadow);
7662		}
7663	},
7664
7665	_removeIcon: function () {
7666		if (this.options.riseOnHover) {
7667			this.off({
7668				mouseover: this._bringToFront,
7669				mouseout: this._resetZIndex
7670			});
7671		}
7672
7673		remove(this._icon);
7674		this.removeInteractiveTarget(this._icon);
7675
7676		this._icon = null;
7677	},
7678
7679	_removeShadow: function () {
7680		if (this._shadow) {
7681			remove(this._shadow);
7682		}
7683		this._shadow = null;
7684	},
7685
7686	_setPos: function (pos) {
7687		setPosition(this._icon, pos);
7688
7689		if (this._shadow) {
7690			setPosition(this._shadow, pos);
7691		}
7692
7693		this._zIndex = pos.y + this.options.zIndexOffset;
7694
7695		this._resetZIndex();
7696	},
7697
7698	_updateZIndex: function (offset) {
7699		this._icon.style.zIndex = this._zIndex + offset;
7700	},
7701
7702	_animateZoom: function (opt) {
7703		var pos = this._map._latLngToNewLayerPoint(this._latlng, opt.zoom, opt.center).round();
7704
7705		this._setPos(pos);
7706	},
7707
7708	_initInteraction: function () {
7709
7710		if (!this.options.interactive) { return; }
7711
7712		addClass(this._icon, 'leaflet-interactive');
7713
7714		this.addInteractiveTarget(this._icon);
7715
7716		if (MarkerDrag) {
7717			var draggable = this.options.draggable;
7718			if (this.dragging) {
7719				draggable = this.dragging.enabled();
7720				this.dragging.disable();
7721			}
7722
7723			this.dragging = new MarkerDrag(this);
7724
7725			if (draggable) {
7726				this.dragging.enable();
7727			}
7728		}
7729	},
7730
7731	// @method setOpacity(opacity: Number): this
7732	// Changes the opacity of the marker.
7733	setOpacity: function (opacity) {
7734		this.options.opacity = opacity;
7735		if (this._map) {
7736			this._updateOpacity();
7737		}
7738
7739		return this;
7740	},
7741
7742	_updateOpacity: function () {
7743		var opacity = this.options.opacity;
7744
7745		setOpacity(this._icon, opacity);
7746
7747		if (this._shadow) {
7748			setOpacity(this._shadow, opacity);
7749		}
7750	},
7751
7752	_bringToFront: function () {
7753		this._updateZIndex(this.options.riseOffset);
7754	},
7755
7756	_resetZIndex: function () {
7757		this._updateZIndex(0);
7758	},
7759
7760	_getPopupAnchor: function () {
7761		return this.options.icon.options.popupAnchor;
7762	},
7763
7764	_getTooltipAnchor: function () {
7765		return this.options.icon.options.tooltipAnchor;
7766	}
7767});
7768
7769
7770// factory L.marker(latlng: LatLng, options? : Marker options)
7771
7772// @factory L.marker(latlng: LatLng, options? : Marker options)
7773// Instantiates a Marker object given a geographical point and optionally an options object.
7774function marker(latlng, options) {
7775	return new Marker(latlng, options);
7776}
7777
7778/*
7779 * @class Path
7780 * @aka L.Path
7781 * @inherits Interactive layer
7782 *
7783 * An abstract class that contains options and constants shared between vector
7784 * overlays (Polygon, Polyline, Circle). Do not use it directly. Extends `Layer`.
7785 */
7786
7787var Path = Layer.extend({
7788
7789	// @section
7790	// @aka Path options
7791	options: {
7792		// @option stroke: Boolean = true
7793		// Whether to draw stroke along the path. Set it to `false` to disable borders on polygons or circles.
7794		stroke: true,
7795
7796		// @option color: String = '#3388ff'
7797		// Stroke color
7798		color: '#3388ff',
7799
7800		// @option weight: Number = 3
7801		// Stroke width in pixels
7802		weight: 3,
7803
7804		// @option opacity: Number = 1.0
7805		// Stroke opacity
7806		opacity: 1,
7807
7808		// @option lineCap: String= 'round'
7809		// A string that defines [shape to be used at the end](https://developer.mozilla.org/docs/Web/SVG/Attribute/stroke-linecap) of the stroke.
7810		lineCap: 'round',
7811
7812		// @option lineJoin: String = 'round'
7813		// A string that defines [shape to be used at the corners](https://developer.mozilla.org/docs/Web/SVG/Attribute/stroke-linejoin) of the stroke.
7814		lineJoin: 'round',
7815
7816		// @option dashArray: String = null
7817		// A string that defines the stroke [dash pattern](https://developer.mozilla.org/docs/Web/SVG/Attribute/stroke-dasharray). Doesn't work on `Canvas`-powered layers in [some old browsers](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/setLineDash#Browser_compatibility).
7818		dashArray: null,
7819
7820		// @option dashOffset: String = null
7821		// A string that defines the [distance into the dash pattern to start the dash](https://developer.mozilla.org/docs/Web/SVG/Attribute/stroke-dashoffset). Doesn't work on `Canvas`-powered layers in [some old browsers](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/setLineDash#Browser_compatibility).
7822		dashOffset: null,
7823
7824		// @option fill: Boolean = depends
7825		// Whether to fill the path with color. Set it to `false` to disable filling on polygons or circles.
7826		fill: false,
7827
7828		// @option fillColor: String = *
7829		// Fill color. Defaults to the value of the [`color`](#path-color) option
7830		fillColor: null,
7831
7832		// @option fillOpacity: Number = 0.2
7833		// Fill opacity.
7834		fillOpacity: 0.2,
7835
7836		// @option fillRule: String = 'evenodd'
7837		// A string that defines [how the inside of a shape](https://developer.mozilla.org/docs/Web/SVG/Attribute/fill-rule) is determined.
7838		fillRule: 'evenodd',
7839
7840		// className: '',
7841
7842		// Option inherited from "Interactive layer" abstract class
7843		interactive: true,
7844
7845		// @option bubblingMouseEvents: Boolean = true
7846		// When `true`, a mouse event on this path will trigger the same event on the map
7847		// (unless [`L.DomEvent.stopPropagation`](#domevent-stoppropagation) is used).
7848		bubblingMouseEvents: true
7849	},
7850
7851	beforeAdd: function (map) {
7852		// Renderer is set here because we need to call renderer.getEvents
7853		// before this.getEvents.
7854		this._renderer = map.getRenderer(this);
7855	},
7856
7857	onAdd: function () {
7858		this._renderer._initPath(this);
7859		this._reset();
7860		this._renderer._addPath(this);
7861	},
7862
7863	onRemove: function () {
7864		this._renderer._removePath(this);
7865	},
7866
7867	// @method redraw(): this
7868	// Redraws the layer. Sometimes useful after you changed the coordinates that the path uses.
7869	redraw: function () {
7870		if (this._map) {
7871			this._renderer._updatePath(this);
7872		}
7873		return this;
7874	},
7875
7876	// @method setStyle(style: Path options): this
7877	// Changes the appearance of a Path based on the options in the `Path options` object.
7878	setStyle: function (style) {
7879		setOptions(this, style);
7880		if (this._renderer) {
7881			this._renderer._updateStyle(this);
7882		}
7883		return this;
7884	},
7885
7886	// @method bringToFront(): this
7887	// Brings the layer to the top of all path layers.
7888	bringToFront: function () {
7889		if (this._renderer) {
7890			this._renderer._bringToFront(this);
7891		}
7892		return this;
7893	},
7894
7895	// @method bringToBack(): this
7896	// Brings the layer to the bottom of all path layers.
7897	bringToBack: function () {
7898		if (this._renderer) {
7899			this._renderer._bringToBack(this);
7900		}
7901		return this;
7902	},
7903
7904	getElement: function () {
7905		return this._path;
7906	},
7907
7908	_reset: function () {
7909		// defined in child classes
7910		this._project();
7911		this._update();
7912	},
7913
7914	_clickTolerance: function () {
7915		// used when doing hit detection for Canvas layers
7916		return (this.options.stroke ? this.options.weight / 2 : 0) + this._renderer.options.tolerance;
7917	}
7918});
7919
7920/*
7921 * @class CircleMarker
7922 * @aka L.CircleMarker
7923 * @inherits Path
7924 *
7925 * A circle of a fixed size with radius specified in pixels. Extends `Path`.
7926 */
7927
7928var CircleMarker = Path.extend({
7929
7930	// @section
7931	// @aka CircleMarker options
7932	options: {
7933		fill: true,
7934
7935		// @option radius: Number = 10
7936		// Radius of the circle marker, in pixels
7937		radius: 10
7938	},
7939
7940	initialize: function (latlng, options) {
7941		setOptions(this, options);
7942		this._latlng = toLatLng(latlng);
7943		this._radius = this.options.radius;
7944	},
7945
7946	// @method setLatLng(latLng: LatLng): this
7947	// Sets the position of a circle marker to a new location.
7948	setLatLng: function (latlng) {
7949		this._latlng = toLatLng(latlng);
7950		this.redraw();
7951		return this.fire('move', {latlng: this._latlng});
7952	},
7953
7954	// @method getLatLng(): LatLng
7955	// Returns the current geographical position of the circle marker
7956	getLatLng: function () {
7957		return this._latlng;
7958	},
7959
7960	// @method setRadius(radius: Number): this
7961	// Sets the radius of a circle marker. Units are in pixels.
7962	setRadius: function (radius) {
7963		this.options.radius = this._radius = radius;
7964		return this.redraw();
7965	},
7966
7967	// @method getRadius(): Number
7968	// Returns the current radius of the circle
7969	getRadius: function () {
7970		return this._radius;
7971	},
7972
7973	setStyle : function (options) {
7974		var radius = options && options.radius || this._radius;
7975		Path.prototype.setStyle.call(this, options);
7976		this.setRadius(radius);
7977		return this;
7978	},
7979
7980	_project: function () {
7981		this._point = this._map.latLngToLayerPoint(this._latlng);
7982		this._updateBounds();
7983	},
7984
7985	_updateBounds: function () {
7986		var r = this._radius,
7987		    r2 = this._radiusY || r,
7988		    w = this._clickTolerance(),
7989		    p = [r + w, r2 + w];
7990		this._pxBounds = new Bounds(this._point.subtract(p), this._point.add(p));
7991	},
7992
7993	_update: function () {
7994		if (this._map) {
7995			this._updatePath();
7996		}
7997	},
7998
7999	_updatePath: function () {
8000		this._renderer._updateCircle(this);
8001	},
8002
8003	_empty: function () {
8004		return this._radius && !this._renderer._bounds.intersects(this._pxBounds);
8005	},
8006
8007	// Needed by the `Canvas` renderer for interactivity
8008	_containsPoint: function (p) {
8009		return p.distanceTo(this._point) <= this._radius + this._clickTolerance();
8010	}
8011});
8012
8013
8014// @factory L.circleMarker(latlng: LatLng, options?: CircleMarker options)
8015// Instantiates a circle marker object given a geographical point, and an optional options object.
8016function circleMarker(latlng, options) {
8017	return new CircleMarker(latlng, options);
8018}
8019
8020/*
8021 * @class Circle
8022 * @aka L.Circle
8023 * @inherits CircleMarker
8024 *
8025 * A class for drawing circle overlays on a map. Extends `CircleMarker`.
8026 *
8027 * It's an approximation and starts to diverge from a real circle closer to poles (due to projection distortion).
8028 *
8029 * @example
8030 *
8031 * ```js
8032 * L.circle([50.5, 30.5], {radius: 200}).addTo(map);
8033 * ```
8034 */
8035
8036var Circle = CircleMarker.extend({
8037
8038	initialize: function (latlng, options, legacyOptions) {
8039		if (typeof options === 'number') {
8040			// Backwards compatibility with 0.7.x factory (latlng, radius, options?)
8041			options = extend({}, legacyOptions, {radius: options});
8042		}
8043		setOptions(this, options);
8044		this._latlng = toLatLng(latlng);
8045
8046		if (isNaN(this.options.radius)) { throw new Error('Circle radius cannot be NaN'); }
8047
8048		// @section
8049		// @aka Circle options
8050		// @option radius: Number; Radius of the circle, in meters.
8051		this._mRadius = this.options.radius;
8052	},
8053
8054	// @method setRadius(radius: Number): this
8055	// Sets the radius of a circle. Units are in meters.
8056	setRadius: function (radius) {
8057		this._mRadius = radius;
8058		return this.redraw();
8059	},
8060
8061	// @method getRadius(): Number
8062	// Returns the current radius of a circle. Units are in meters.
8063	getRadius: function () {
8064		return this._mRadius;
8065	},
8066
8067	// @method getBounds(): LatLngBounds
8068	// Returns the `LatLngBounds` of the path.
8069	getBounds: function () {
8070		var half = [this._radius, this._radiusY || this._radius];
8071
8072		return new LatLngBounds(
8073			this._map.layerPointToLatLng(this._point.subtract(half)),
8074			this._map.layerPointToLatLng(this._point.add(half)));
8075	},
8076
8077	setStyle: Path.prototype.setStyle,
8078
8079	_project: function () {
8080
8081		var lng = this._latlng.lng,
8082		    lat = this._latlng.lat,
8083		    map = this._map,
8084		    crs = map.options.crs;
8085
8086		if (crs.distance === Earth.distance) {
8087			var d = Math.PI / 180,
8088			    latR = (this._mRadius / Earth.R) / d,
8089			    top = map.project([lat + latR, lng]),
8090			    bottom = map.project([lat - latR, lng]),
8091			    p = top.add(bottom).divideBy(2),
8092			    lat2 = map.unproject(p).lat,
8093			    lngR = Math.acos((Math.cos(latR * d) - Math.sin(lat * d) * Math.sin(lat2 * d)) /
8094			            (Math.cos(lat * d) * Math.cos(lat2 * d))) / d;
8095
8096			if (isNaN(lngR) || lngR === 0) {
8097				lngR = latR / Math.cos(Math.PI / 180 * lat); // Fallback for edge case, #2425
8098			}
8099
8100			this._point = p.subtract(map.getPixelOrigin());
8101			this._radius = isNaN(lngR) ? 0 : p.x - map.project([lat2, lng - lngR]).x;
8102			this._radiusY = p.y - top.y;
8103
8104		} else {
8105			var latlng2 = crs.unproject(crs.project(this._latlng).subtract([this._mRadius, 0]));
8106
8107			this._point = map.latLngToLayerPoint(this._latlng);
8108			this._radius = this._point.x - map.latLngToLayerPoint(latlng2).x;
8109		}
8110
8111		this._updateBounds();
8112	}
8113});
8114
8115// @factory L.circle(latlng: LatLng, options?: Circle options)
8116// Instantiates a circle object given a geographical point, and an options object
8117// which contains the circle radius.
8118// @alternative
8119// @factory L.circle(latlng: LatLng, radius: Number, options?: Circle options)
8120// Obsolete way of instantiating a circle, for compatibility with 0.7.x code.
8121// Do not use in new applications or plugins.
8122function circle(latlng, options, legacyOptions) {
8123	return new Circle(latlng, options, legacyOptions);
8124}
8125
8126/*
8127 * @class Polyline
8128 * @aka L.Polyline
8129 * @inherits Path
8130 *
8131 * A class for drawing polyline overlays on a map. Extends `Path`.
8132 *
8133 * @example
8134 *
8135 * ```js
8136 * // create a red polyline from an array of LatLng points
8137 * var latlngs = [
8138 * 	[45.51, -122.68],
8139 * 	[37.77, -122.43],
8140 * 	[34.04, -118.2]
8141 * ];
8142 *
8143 * var polyline = L.polyline(latlngs, {color: 'red'}).addTo(map);
8144 *
8145 * // zoom the map to the polyline
8146 * map.fitBounds(polyline.getBounds());
8147 * ```
8148 *
8149 * You can also pass a multi-dimensional array to represent a `MultiPolyline` shape:
8150 *
8151 * ```js
8152 * // create a red polyline from an array of arrays of LatLng points
8153 * var latlngs = [
8154 * 	[[45.51, -122.68],
8155 * 	 [37.77, -122.43],
8156 * 	 [34.04, -118.2]],
8157 * 	[[40.78, -73.91],
8158 * 	 [41.83, -87.62],
8159 * 	 [32.76, -96.72]]
8160 * ];
8161 * ```
8162 */
8163
8164
8165var Polyline = Path.extend({
8166
8167	// @section
8168	// @aka Polyline options
8169	options: {
8170		// @option smoothFactor: Number = 1.0
8171		// How much to simplify the polyline on each zoom level. More means
8172		// better performance and smoother look, and less means more accurate representation.
8173		smoothFactor: 1.0,
8174
8175		// @option noClip: Boolean = false
8176		// Disable polyline clipping.
8177		noClip: false
8178	},
8179
8180	initialize: function (latlngs, options) {
8181		setOptions(this, options);
8182		this._setLatLngs(latlngs);
8183	},
8184
8185	// @method getLatLngs(): LatLng[]
8186	// Returns an array of the points in the path, or nested arrays of points in case of multi-polyline.
8187	getLatLngs: function () {
8188		return this._latlngs;
8189	},
8190
8191	// @method setLatLngs(latlngs: LatLng[]): this
8192	// Replaces all the points in the polyline with the given array of geographical points.
8193	setLatLngs: function (latlngs) {
8194		this._setLatLngs(latlngs);
8195		return this.redraw();
8196	},
8197
8198	// @method isEmpty(): Boolean
8199	// Returns `true` if the Polyline has no LatLngs.
8200	isEmpty: function () {
8201		return !this._latlngs.length;
8202	},
8203
8204	// @method closestLayerPoint(p: Point): Point
8205	// Returns the point closest to `p` on the Polyline.
8206	closestLayerPoint: function (p) {
8207		var minDistance = Infinity,
8208		    minPoint = null,
8209		    closest = _sqClosestPointOnSegment,
8210		    p1, p2;
8211
8212		for (var j = 0, jLen = this._parts.length; j < jLen; j++) {
8213			var points = this._parts[j];
8214
8215			for (var i = 1, len = points.length; i < len; i++) {
8216				p1 = points[i - 1];
8217				p2 = points[i];
8218
8219				var sqDist = closest(p, p1, p2, true);
8220
8221				if (sqDist < minDistance) {
8222					minDistance = sqDist;
8223					minPoint = closest(p, p1, p2);
8224				}
8225			}
8226		}
8227		if (minPoint) {
8228			minPoint.distance = Math.sqrt(minDistance);
8229		}
8230		return minPoint;
8231	},
8232
8233	// @method getCenter(): LatLng
8234	// Returns the center ([centroid](http://en.wikipedia.org/wiki/Centroid)) of the polyline.
8235	getCenter: function () {
8236		// throws error when not yet added to map as this center calculation requires projected coordinates
8237		if (!this._map) {
8238			throw new Error('Must add layer to map before using getCenter()');
8239		}
8240
8241		var i, halfDist, segDist, dist, p1, p2, ratio,
8242		    points = this._rings[0],
8243		    len = points.length;
8244
8245		if (!len) { return null; }
8246
8247		// polyline centroid algorithm; only uses the first ring if there are multiple
8248
8249		for (i = 0, halfDist = 0; i < len - 1; i++) {
8250			halfDist += points[i].distanceTo(points[i + 1]) / 2;
8251		}
8252
8253		// The line is so small in the current view that all points are on the same pixel.
8254		if (halfDist === 0) {
8255			return this._map.layerPointToLatLng(points[0]);
8256		}
8257
8258		for (i = 0, dist = 0; i < len - 1; i++) {
8259			p1 = points[i];
8260			p2 = points[i + 1];
8261			segDist = p1.distanceTo(p2);
8262			dist += segDist;
8263
8264			if (dist > halfDist) {
8265				ratio = (dist - halfDist) / segDist;
8266				return this._map.layerPointToLatLng([
8267					p2.x - ratio * (p2.x - p1.x),
8268					p2.y - ratio * (p2.y - p1.y)
8269				]);
8270			}
8271		}
8272	},
8273
8274	// @method getBounds(): LatLngBounds
8275	// Returns the `LatLngBounds` of the path.
8276	getBounds: function () {
8277		return this._bounds;
8278	},
8279
8280	// @method addLatLng(latlng: LatLng, latlngs? LatLng[]): this
8281	// Adds a given point to the polyline. By default, adds to the first ring of
8282	// the polyline in case of a multi-polyline, but can be overridden by passing
8283	// a specific ring as a LatLng array (that you can earlier access with [`getLatLngs`](#polyline-getlatlngs)).
8284	addLatLng: function (latlng, latlngs) {
8285		latlngs = latlngs || this._defaultShape();
8286		latlng = toLatLng(latlng);
8287		latlngs.push(latlng);
8288		this._bounds.extend(latlng);
8289		return this.redraw();
8290	},
8291
8292	_setLatLngs: function (latlngs) {
8293		this._bounds = new LatLngBounds();
8294		this._latlngs = this._convertLatLngs(latlngs);
8295	},
8296
8297	_defaultShape: function () {
8298		return isFlat(this._latlngs) ? this._latlngs : this._latlngs[0];
8299	},
8300
8301	// recursively convert latlngs input into actual LatLng instances; calculate bounds along the way
8302	_convertLatLngs: function (latlngs) {
8303		var result = [],
8304		    flat = isFlat(latlngs);
8305
8306		for (var i = 0, len = latlngs.length; i < len; i++) {
8307			if (flat) {
8308				result[i] = toLatLng(latlngs[i]);
8309				this._bounds.extend(result[i]);
8310			} else {
8311				result[i] = this._convertLatLngs(latlngs[i]);
8312			}
8313		}
8314
8315		return result;
8316	},
8317
8318	_project: function () {
8319		var pxBounds = new Bounds();
8320		this._rings = [];
8321		this._projectLatlngs(this._latlngs, this._rings, pxBounds);
8322
8323		var w = this._clickTolerance(),
8324		    p = new Point(w, w);
8325
8326		if (this._bounds.isValid() && pxBounds.isValid()) {
8327			pxBounds.min._subtract(p);
8328			pxBounds.max._add(p);
8329			this._pxBounds = pxBounds;
8330		}
8331	},
8332
8333	// recursively turns latlngs into a set of rings with projected coordinates
8334	_projectLatlngs: function (latlngs, result, projectedBounds) {
8335		var flat = latlngs[0] instanceof LatLng,
8336		    len = latlngs.length,
8337		    i, ring;
8338
8339		if (flat) {
8340			ring = [];
8341			for (i = 0; i < len; i++) {
8342				ring[i] = this._map.latLngToLayerPoint(latlngs[i]);
8343				projectedBounds.extend(ring[i]);
8344			}
8345			result.push(ring);
8346		} else {
8347			for (i = 0; i < len; i++) {
8348				this._projectLatlngs(latlngs[i], result, projectedBounds);
8349			}
8350		}
8351	},
8352
8353	// clip polyline by renderer bounds so that we have less to render for performance
8354	_clipPoints: function () {
8355		var bounds = this._renderer._bounds;
8356
8357		this._parts = [];
8358		if (!this._pxBounds || !this._pxBounds.intersects(bounds)) {
8359			return;
8360		}
8361
8362		if (this.options.noClip) {
8363			this._parts = this._rings;
8364			return;
8365		}
8366
8367		var parts = this._parts,
8368		    i, j, k, len, len2, segment, points;
8369
8370		for (i = 0, k = 0, len = this._rings.length; i < len; i++) {
8371			points = this._rings[i];
8372
8373			for (j = 0, len2 = points.length; j < len2 - 1; j++) {
8374				segment = clipSegment(points[j], points[j + 1], bounds, j, true);
8375
8376				if (!segment) { continue; }
8377
8378				parts[k] = parts[k] || [];
8379				parts[k].push(segment[0]);
8380
8381				// if segment goes out of screen, or it's the last one, it's the end of the line part
8382				if ((segment[1] !== points[j + 1]) || (j === len2 - 2)) {
8383					parts[k].push(segment[1]);
8384					k++;
8385				}
8386			}
8387		}
8388	},
8389
8390	// simplify each clipped part of the polyline for performance
8391	_simplifyPoints: function () {
8392		var parts = this._parts,
8393		    tolerance = this.options.smoothFactor;
8394
8395		for (var i = 0, len = parts.length; i < len; i++) {
8396			parts[i] = simplify(parts[i], tolerance);
8397		}
8398	},
8399
8400	_update: function () {
8401		if (!this._map) { return; }
8402
8403		this._clipPoints();
8404		this._simplifyPoints();
8405		this._updatePath();
8406	},
8407
8408	_updatePath: function () {
8409		this._renderer._updatePoly(this);
8410	},
8411
8412	// Needed by the `Canvas` renderer for interactivity
8413	_containsPoint: function (p, closed) {
8414		var i, j, k, len, len2, part,
8415		    w = this._clickTolerance();
8416
8417		if (!this._pxBounds || !this._pxBounds.contains(p)) { return false; }
8418
8419		// hit detection for polylines
8420		for (i = 0, len = this._parts.length; i < len; i++) {
8421			part = this._parts[i];
8422
8423			for (j = 0, len2 = part.length, k = len2 - 1; j < len2; k = j++) {
8424				if (!closed && (j === 0)) { continue; }
8425
8426				if (pointToSegmentDistance(p, part[k], part[j]) <= w) {
8427					return true;
8428				}
8429			}
8430		}
8431		return false;
8432	}
8433});
8434
8435// @factory L.polyline(latlngs: LatLng[], options?: Polyline options)
8436// Instantiates a polyline object given an array of geographical points and
8437// optionally an options object. You can create a `Polyline` object with
8438// multiple separate lines (`MultiPolyline`) by passing an array of arrays
8439// of geographic points.
8440function polyline(latlngs, options) {
8441	return new Polyline(latlngs, options);
8442}
8443
8444// Retrocompat. Allow plugins to support Leaflet versions before and after 1.1.
8445Polyline._flat = _flat;
8446
8447/*
8448 * @class Polygon
8449 * @aka L.Polygon
8450 * @inherits Polyline
8451 *
8452 * A class for drawing polygon overlays on a map. Extends `Polyline`.
8453 *
8454 * Note that points you pass when creating a polygon shouldn't have an additional last point equal to the first one — it's better to filter out such points.
8455 *
8456 *
8457 * @example
8458 *
8459 * ```js
8460 * // create a red polygon from an array of LatLng points
8461 * var latlngs = [[37, -109.05],[41, -109.03],[41, -102.05],[37, -102.04]];
8462 *
8463 * var polygon = L.polygon(latlngs, {color: 'red'}).addTo(map);
8464 *
8465 * // zoom the map to the polygon
8466 * map.fitBounds(polygon.getBounds());
8467 * ```
8468 *
8469 * You can also pass an array of arrays of latlngs, with the first array representing the outer shape and the other arrays representing holes in the outer shape:
8470 *
8471 * ```js
8472 * var latlngs = [
8473 *   [[37, -109.05],[41, -109.03],[41, -102.05],[37, -102.04]], // outer ring
8474 *   [[37.29, -108.58],[40.71, -108.58],[40.71, -102.50],[37.29, -102.50]] // hole
8475 * ];
8476 * ```
8477 *
8478 * Additionally, you can pass a multi-dimensional array to represent a MultiPolygon shape.
8479 *
8480 * ```js
8481 * var latlngs = [
8482 *   [ // first polygon
8483 *     [[37, -109.05],[41, -109.03],[41, -102.05],[37, -102.04]], // outer ring
8484 *     [[37.29, -108.58],[40.71, -108.58],[40.71, -102.50],[37.29, -102.50]] // hole
8485 *   ],
8486 *   [ // second polygon
8487 *     [[41, -111.03],[45, -111.04],[45, -104.05],[41, -104.05]]
8488 *   ]
8489 * ];
8490 * ```
8491 */
8492
8493var Polygon = Polyline.extend({
8494
8495	options: {
8496		fill: true
8497	},
8498
8499	isEmpty: function () {
8500		return !this._latlngs.length || !this._latlngs[0].length;
8501	},
8502
8503	getCenter: function () {
8504		// throws error when not yet added to map as this center calculation requires projected coordinates
8505		if (!this._map) {
8506			throw new Error('Must add layer to map before using getCenter()');
8507		}
8508
8509		var i, j, p1, p2, f, area, x, y, center,
8510		    points = this._rings[0],
8511		    len = points.length;
8512
8513		if (!len) { return null; }
8514
8515		// polygon centroid algorithm; only uses the first ring if there are multiple
8516
8517		area = x = y = 0;
8518
8519		for (i = 0, j = len - 1; i < len; j = i++) {
8520			p1 = points[i];
8521			p2 = points[j];
8522
8523			f = p1.y * p2.x - p2.y * p1.x;
8524			x += (p1.x + p2.x) * f;
8525			y += (p1.y + p2.y) * f;
8526			area += f * 3;
8527		}
8528
8529		if (area === 0) {
8530			// Polygon is so small that all points are on same pixel.
8531			center = points[0];
8532		} else {
8533			center = [x / area, y / area];
8534		}
8535		return this._map.layerPointToLatLng(center);
8536	},
8537
8538	_convertLatLngs: function (latlngs) {
8539		var result = Polyline.prototype._convertLatLngs.call(this, latlngs),
8540		    len = result.length;
8541
8542		// remove last point if it equals first one
8543		if (len >= 2 && result[0] instanceof LatLng && result[0].equals(result[len - 1])) {
8544			result.pop();
8545		}
8546		return result;
8547	},
8548
8549	_setLatLngs: function (latlngs) {
8550		Polyline.prototype._setLatLngs.call(this, latlngs);
8551		if (isFlat(this._latlngs)) {
8552			this._latlngs = [this._latlngs];
8553		}
8554	},
8555
8556	_defaultShape: function () {
8557		return isFlat(this._latlngs[0]) ? this._latlngs[0] : this._latlngs[0][0];
8558	},
8559
8560	_clipPoints: function () {
8561		// polygons need a different clipping algorithm so we redefine that
8562
8563		var bounds = this._renderer._bounds,
8564		    w = this.options.weight,
8565		    p = new Point(w, w);
8566
8567		// increase clip padding by stroke width to avoid stroke on clip edges
8568		bounds = new Bounds(bounds.min.subtract(p), bounds.max.add(p));
8569
8570		this._parts = [];
8571		if (!this._pxBounds || !this._pxBounds.intersects(bounds)) {
8572			return;
8573		}
8574
8575		if (this.options.noClip) {
8576			this._parts = this._rings;
8577			return;
8578		}
8579
8580		for (var i = 0, len = this._rings.length, clipped; i < len; i++) {
8581			clipped = clipPolygon(this._rings[i], bounds, true);
8582			if (clipped.length) {
8583				this._parts.push(clipped);
8584			}
8585		}
8586	},
8587
8588	_updatePath: function () {
8589		this._renderer._updatePoly(this, true);
8590	},
8591
8592	// Needed by the `Canvas` renderer for interactivity
8593	_containsPoint: function (p) {
8594		var inside = false,
8595		    part, p1, p2, i, j, k, len, len2;
8596
8597		if (!this._pxBounds || !this._pxBounds.contains(p)) { return false; }
8598
8599		// ray casting algorithm for detecting if point is in polygon
8600		for (i = 0, len = this._parts.length; i < len; i++) {
8601			part = this._parts[i];
8602
8603			for (j = 0, len2 = part.length, k = len2 - 1; j < len2; k = j++) {
8604				p1 = part[j];
8605				p2 = part[k];
8606
8607				if (((p1.y > p.y) !== (p2.y > p.y)) && (p.x < (p2.x - p1.x) * (p.y - p1.y) / (p2.y - p1.y) + p1.x)) {
8608					inside = !inside;
8609				}
8610			}
8611		}
8612
8613		// also check if it's on polygon stroke
8614		return inside || Polyline.prototype._containsPoint.call(this, p, true);
8615	}
8616
8617});
8618
8619
8620// @factory L.polygon(latlngs: LatLng[], options?: Polyline options)
8621function polygon(latlngs, options) {
8622	return new Polygon(latlngs, options);
8623}
8624
8625/*
8626 * @class GeoJSON
8627 * @aka L.GeoJSON
8628 * @inherits FeatureGroup
8629 *
8630 * Represents a GeoJSON object or an array of GeoJSON objects. Allows you to parse
8631 * GeoJSON data and display it on the map. Extends `FeatureGroup`.
8632 *
8633 * @example
8634 *
8635 * ```js
8636 * L.geoJSON(data, {
8637 * 	style: function (feature) {
8638 * 		return {color: feature.properties.color};
8639 * 	}
8640 * }).bindPopup(function (layer) {
8641 * 	return layer.feature.properties.description;
8642 * }).addTo(map);
8643 * ```
8644 */
8645
8646var GeoJSON = FeatureGroup.extend({
8647
8648	/* @section
8649	 * @aka GeoJSON options
8650	 *
8651	 * @option pointToLayer: Function = *
8652	 * A `Function` defining how GeoJSON points spawn Leaflet layers. It is internally
8653	 * called when data is added, passing the GeoJSON point feature and its `LatLng`.
8654	 * The default is to spawn a default `Marker`:
8655	 * ```js
8656	 * function(geoJsonPoint, latlng) {
8657	 * 	return L.marker(latlng);
8658	 * }
8659	 * ```
8660	 *
8661	 * @option style: Function = *
8662	 * A `Function` defining the `Path options` for styling GeoJSON lines and polygons,
8663	 * called internally when data is added.
8664	 * The default value is to not override any defaults:
8665	 * ```js
8666	 * function (geoJsonFeature) {
8667	 * 	return {}
8668	 * }
8669	 * ```
8670	 *
8671	 * @option onEachFeature: Function = *
8672	 * A `Function` that will be called once for each created `Feature`, after it has
8673	 * been created and styled. Useful for attaching events and popups to features.
8674	 * The default is to do nothing with the newly created layers:
8675	 * ```js
8676	 * function (feature, layer) {}
8677	 * ```
8678	 *
8679	 * @option filter: Function = *
8680	 * A `Function` that will be used to decide whether to include a feature or not.
8681	 * The default is to include all features:
8682	 * ```js
8683	 * function (geoJsonFeature) {
8684	 * 	return true;
8685	 * }
8686	 * ```
8687	 * Note: dynamically changing the `filter` option will have effect only on newly
8688	 * added data. It will _not_ re-evaluate already included features.
8689	 *
8690	 * @option coordsToLatLng: Function = *
8691	 * A `Function` that will be used for converting GeoJSON coordinates to `LatLng`s.
8692	 * The default is the `coordsToLatLng` static method.
8693	 */
8694
8695	initialize: function (geojson, options) {
8696		setOptions(this, options);
8697
8698		this._layers = {};
8699
8700		if (geojson) {
8701			this.addData(geojson);
8702		}
8703	},
8704
8705	// @method addData( <GeoJSON> data ): this
8706	// Adds a GeoJSON object to the layer.
8707	addData: function (geojson) {
8708		var features = isArray(geojson) ? geojson : geojson.features,
8709		    i, len, feature;
8710
8711		if (features) {
8712			for (i = 0, len = features.length; i < len; i++) {
8713				// only add this if geometry or geometries are set and not null
8714				feature = features[i];
8715				if (feature.geometries || feature.geometry || feature.features || feature.coordinates) {
8716					this.addData(feature);
8717				}
8718			}
8719			return this;
8720		}
8721
8722		var options = this.options;
8723
8724		if (options.filter && !options.filter(geojson)) { return this; }
8725
8726		var layer = geometryToLayer(geojson, options);
8727		if (!layer) {
8728			return this;
8729		}
8730		layer.feature = asFeature(geojson);
8731
8732		layer.defaultOptions = layer.options;
8733		this.resetStyle(layer);
8734
8735		if (options.onEachFeature) {
8736			options.onEachFeature(geojson, layer);
8737		}
8738
8739		return this.addLayer(layer);
8740	},
8741
8742	// @method resetStyle( <Path> layer ): this
8743	// Resets the given vector layer's style to the original GeoJSON style, useful for resetting style after hover events.
8744	resetStyle: function (layer) {
8745		// reset any custom styles
8746		layer.options = extend({}, layer.defaultOptions);
8747		this._setLayerStyle(layer, this.options.style);
8748		return this;
8749	},
8750
8751	// @method setStyle( <Function> style ): this
8752	// Changes styles of GeoJSON vector layers with the given style function.
8753	setStyle: function (style) {
8754		return this.eachLayer(function (layer) {
8755			this._setLayerStyle(layer, style);
8756		}, this);
8757	},
8758
8759	_setLayerStyle: function (layer, style) {
8760		if (typeof style === 'function') {
8761			style = style(layer.feature);
8762		}
8763		if (layer.setStyle) {
8764			layer.setStyle(style);
8765		}
8766	}
8767});
8768
8769// @section
8770// There are several static functions which can be called without instantiating L.GeoJSON:
8771
8772// @function geometryToLayer(featureData: Object, options?: GeoJSON options): Layer
8773// Creates a `Layer` from a given GeoJSON feature. Can use a custom
8774// [`pointToLayer`](#geojson-pointtolayer) and/or [`coordsToLatLng`](#geojson-coordstolatlng)
8775// functions if provided as options.
8776function geometryToLayer(geojson, options) {
8777
8778	var geometry = geojson.type === 'Feature' ? geojson.geometry : geojson,
8779	    coords = geometry ? geometry.coordinates : null,
8780	    layers = [],
8781	    pointToLayer = options && options.pointToLayer,
8782	    _coordsToLatLng = options && options.coordsToLatLng || coordsToLatLng,
8783	    latlng, latlngs, i, len;
8784
8785	if (!coords && !geometry) {
8786		return null;
8787	}
8788
8789	switch (geometry.type) {
8790	case 'Point':
8791		latlng = _coordsToLatLng(coords);
8792		return pointToLayer ? pointToLayer(geojson, latlng) : new Marker(latlng);
8793
8794	case 'MultiPoint':
8795		for (i = 0, len = coords.length; i < len; i++) {
8796			latlng = _coordsToLatLng(coords[i]);
8797			layers.push(pointToLayer ? pointToLayer(geojson, latlng) : new Marker(latlng));
8798		}
8799		return new FeatureGroup(layers);
8800
8801	case 'LineString':
8802	case 'MultiLineString':
8803		latlngs = coordsToLatLngs(coords, geometry.type === 'LineString' ? 0 : 1, _coordsToLatLng);
8804		return new Polyline(latlngs, options);
8805
8806	case 'Polygon':
8807	case 'MultiPolygon':
8808		latlngs = coordsToLatLngs(coords, geometry.type === 'Polygon' ? 1 : 2, _coordsToLatLng);
8809		return new Polygon(latlngs, options);
8810
8811	case 'GeometryCollection':
8812		for (i = 0, len = geometry.geometries.length; i < len; i++) {
8813			var layer = geometryToLayer({
8814				geometry: geometry.geometries[i],
8815				type: 'Feature',
8816				properties: geojson.properties
8817			}, options);
8818
8819			if (layer) {
8820				layers.push(layer);
8821			}
8822		}
8823		return new FeatureGroup(layers);
8824
8825	default:
8826		throw new Error('Invalid GeoJSON object.');
8827	}
8828}
8829
8830// @function coordsToLatLng(coords: Array): LatLng
8831// Creates a `LatLng` object from an array of 2 numbers (longitude, latitude)
8832// or 3 numbers (longitude, latitude, altitude) used in GeoJSON for points.
8833function coordsToLatLng(coords) {
vendor: 12,744 bytes, lines 8834-9296
8834	return new LatLng(coords[1], coords[0], coords[2]);
8835}
8836
8837// @function coordsToLatLngs(coords: Array, levelsDeep?: Number, coordsToLatLng?: Function): Array
8838// Creates a multidimensional array of `LatLng`s from a GeoJSON coordinates array.
8839// `levelsDeep` specifies the nesting level (0 is for an array of points, 1 for an array of arrays of points, etc., 0 by default).
8840// Can use a custom [`coordsToLatLng`](#geojson-coordstolatlng) function.
8841function coordsToLatLngs(coords, levelsDeep, _coordsToLatLng) {
8842	var latlngs = [];
8843
8844	for (var i = 0, len = coords.length, latlng; i < len; i++) {
8845		latlng = levelsDeep ?
8846			coordsToLatLngs(coords[i], levelsDeep - 1, _coordsToLatLng) :
8847			(_coordsToLatLng || coordsToLatLng)(coords[i]);
8848
8849		latlngs.push(latlng);
8850	}
8851
8852	return latlngs;
8853}
8854
8855// @function latLngToCoords(latlng: LatLng, precision?: Number): Array
8856// Reverse of [`coordsToLatLng`](#geojson-coordstolatlng)
8857function latLngToCoords(latlng, precision) {
8858	precision = typeof precision === 'number' ? precision : 6;
8859	return latlng.alt !== undefined ?
8860		[formatNum(latlng.lng, precision), formatNum(latlng.lat, precision), formatNum(latlng.alt, precision)] :
8861		[formatNum(latlng.lng, precision), formatNum(latlng.lat, precision)];
8862}
8863
8864// @function latLngsToCoords(latlngs: Array, levelsDeep?: Number, closed?: Boolean): Array
8865// Reverse of [`coordsToLatLngs`](#geojson-coordstolatlngs)
8866// `closed` determines whether the first point should be appended to the end of the array to close the feature, only used when `levelsDeep` is 0. False by default.
8867function latLngsToCoords(latlngs, levelsDeep, closed, precision) {
8868	var coords = [];
8869
8870	for (var i = 0, len = latlngs.length; i < len; i++) {
8871		coords.push(levelsDeep ?
8872			latLngsToCoords(latlngs[i], levelsDeep - 1, closed, precision) :
8873			latLngToCoords(latlngs[i], precision));
8874	}
8875
8876	if (!levelsDeep && closed) {
8877		coords.push(coords[0]);
8878	}
8879
8880	return coords;
8881}
8882
8883function getFeature(layer, newGeometry) {
8884	return layer.feature ?
8885		extend({}, layer.feature, {geometry: newGeometry}) :
8886		asFeature(newGeometry);
8887}
8888
8889// @function asFeature(geojson: Object): Object
8890// Normalize GeoJSON geometries/features into GeoJSON features.
8891function asFeature(geojson) {
8892	if (geojson.type === 'Feature' || geojson.type === 'FeatureCollection') {
8893		return geojson;
8894	}
8895
8896	return {
8897		type: 'Feature',
8898		properties: {},
8899		geometry: geojson
8900	};
8901}
8902
8903var PointToGeoJSON = {
8904	toGeoJSON: function (precision) {
8905		return getFeature(this, {
8906			type: 'Point',
8907			coordinates: latLngToCoords(this.getLatLng(), precision)
8908		});
8909	}
8910};
8911
8912// @namespace Marker
8913// @method toGeoJSON(): Object
8914// Returns a [`GeoJSON`](http://en.wikipedia.org/wiki/GeoJSON) representation of the marker (as a GeoJSON `Point` Feature).
8915Marker.include(PointToGeoJSON);
8916
8917// @namespace CircleMarker
8918// @method toGeoJSON(): Object
8919// Returns a [`GeoJSON`](http://en.wikipedia.org/wiki/GeoJSON) representation of the circle marker (as a GeoJSON `Point` Feature).
8920Circle.include(PointToGeoJSON);
8921CircleMarker.include(PointToGeoJSON);
8922
8923
8924// @namespace Polyline
8925// @method toGeoJSON(): Object
8926// Returns a [`GeoJSON`](http://en.wikipedia.org/wiki/GeoJSON) representation of the polyline (as a GeoJSON `LineString` or `MultiLineString` Feature).
8927Polyline.include({
8928	toGeoJSON: function (precision) {
8929		var multi = !isFlat(this._latlngs);
8930
8931		var coords = latLngsToCoords(this._latlngs, multi ? 1 : 0, false, precision);
8932
8933		return getFeature(this, {
8934			type: (multi ? 'Multi' : '') + 'LineString',
8935			coordinates: coords
8936		});
8937	}
8938});
8939
8940// @namespace Polygon
8941// @method toGeoJSON(): Object
8942// Returns a [`GeoJSON`](http://en.wikipedia.org/wiki/GeoJSON) representation of the polygon (as a GeoJSON `Polygon` or `MultiPolygon` Feature).
8943Polygon.include({
8944	toGeoJSON: function (precision) {
8945		var holes = !isFlat(this._latlngs),
8946		    multi = holes && !isFlat(this._latlngs[0]);
8947
8948		var coords = latLngsToCoords(this._latlngs, multi ? 2 : holes ? 1 : 0, true, precision);
8949
8950		if (!holes) {
8951			coords = [coords];
8952		}
8953
8954		return getFeature(this, {
8955			type: (multi ? 'Multi' : '') + 'Polygon',
8956			coordinates: coords
8957		});
8958	}
8959});
8960
8961
8962// @namespace LayerGroup
8963LayerGroup.include({
8964	toMultiPoint: function (precision) {
8965		var coords = [];
8966
8967		this.eachLayer(function (layer) {
8968			coords.push(layer.toGeoJSON(precision).geometry.coordinates);
8969		});
8970
8971		return getFeature(this, {
8972			type: 'MultiPoint',
8973			coordinates: coords
8974		});
8975	},
8976
8977	// @method toGeoJSON(): Object
8978	// Returns a [`GeoJSON`](http://en.wikipedia.org/wiki/GeoJSON) representation of the layer group (as a GeoJSON `FeatureCollection`, `GeometryCollection`, or `MultiPoint`).
8979	toGeoJSON: function (precision) {
8980
8981		var type = this.feature && this.feature.geometry && this.feature.geometry.type;
8982
8983		if (type === 'MultiPoint') {
8984			return this.toMultiPoint(precision);
8985		}
8986
8987		var isGeometryCollection = type === 'GeometryCollection',
8988		    jsons = [];
8989
8990		this.eachLayer(function (layer) {
8991			if (layer.toGeoJSON) {
8992				var json = layer.toGeoJSON(precision);
8993				if (isGeometryCollection) {
8994					jsons.push(json.geometry);
8995				} else {
8996					var feature = asFeature(json);
8997					// Squash nested feature collections
8998					if (feature.type === 'FeatureCollection') {
8999						jsons.push.apply(jsons, feature.features);
9000					} else {
9001						jsons.push(feature);
9002					}
9003				}
9004			}
9005		});
9006
9007		if (isGeometryCollection) {
9008			return getFeature(this, {
9009				geometries: jsons,
9010				type: 'GeometryCollection'
9011			});
9012		}
9013
9014		return {
9015			type: 'FeatureCollection',
9016			features: jsons
9017		};
9018	}
9019});
9020
9021// @namespace GeoJSON
9022// @factory L.geoJSON(geojson?: Object, options?: GeoJSON options)
9023// Creates a GeoJSON layer. Optionally accepts an object in
9024// [GeoJSON format](https://tools.ietf.org/html/rfc7946) to display on the map
9025// (you can alternatively add it later with `addData` method) and an `options` object.
9026function geoJSON(geojson, options) {
9027	return new GeoJSON(geojson, options);
9028}
9029
9030// Backward compatibility.
9031var geoJson = geoJSON;
9032
9033/*
9034 * @class ImageOverlay
9035 * @aka L.ImageOverlay
9036 * @inherits Interactive layer
9037 *
9038 * Used to load and display a single image over specific bounds of the map. Extends `Layer`.
9039 *
9040 * @example
9041 *
9042 * ```js
9043 * var imageUrl = 'http://www.lib.utexas.edu/maps/historical/newark_nj_1922.jpg',
9044 * 	imageBounds = [[40.712216, -74.22655], [40.773941, -74.12544]];
9045 * L.imageOverlay(imageUrl, imageBounds).addTo(map);
9046 * ```
9047 */
9048
9049var ImageOverlay = Layer.extend({
9050
9051	// @section
9052	// @aka ImageOverlay options
9053	options: {
9054		// @option opacity: Number = 1.0
9055		// The opacity of the image overlay.
9056		opacity: 1,
9057
9058		// @option alt: String = ''
9059		// Text for the `alt` attribute of the image (useful for accessibility).
9060		alt: '',
9061
9062		// @option interactive: Boolean = false
9063		// If `true`, the image overlay will emit [mouse events](#interactive-layer) when clicked or hovered.
9064		interactive: false,
9065
9066		// @option crossOrigin: Boolean|String = false
9067		// Whether the crossOrigin attribute will be added to the image.
9068		// If a String is provided, the image will have its crossOrigin attribute set to the String provided. This is needed if you want to access image pixel data.
9069		// Refer to [CORS Settings](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes) for valid String values.
9070		crossOrigin: false,
9071
9072		// @option errorOverlayUrl: String = ''
9073		// URL to the overlay image to show in place of the overlay that failed to load.
9074		errorOverlayUrl: '',
9075
9076		// @option zIndex: Number = 1
9077		// The explicit [zIndex](https://developer.mozilla.org/docs/Web/CSS/CSS_Positioning/Understanding_z_index) of the overlay layer.
9078		zIndex: 1,
9079
9080		// @option className: String = ''
9081		// A custom class name to assign to the image. Empty by default.
9082		className: ''
9083	},
9084
9085	initialize: function (url, bounds, options) { // (String, LatLngBounds, Object)
9086		this._url = url;
9087		this._bounds = toLatLngBounds(bounds);
9088
9089		setOptions(this, options);
9090	},
9091
9092	onAdd: function () {
9093		if (!this._image) {
9094			this._initImage();
9095
9096			if (this.options.opacity < 1) {
9097				this._updateOpacity();
9098			}
9099		}
9100
9101		if (this.options.interactive) {
9102			addClass(this._image, 'leaflet-interactive');
9103			this.addInteractiveTarget(this._image);
9104		}
9105
9106		this.getPane().appendChild(this._image);
9107		this._reset();
9108	},
9109
9110	onRemove: function () {
9111		remove(this._image);
9112		if (this.options.interactive) {
9113			this.removeInteractiveTarget(this._image);
9114		}
9115	},
9116
9117	// @method setOpacity(opacity: Number): this
9118	// Sets the opacity of the overlay.
9119	setOpacity: function (opacity) {
9120		this.options.opacity = opacity;
9121
9122		if (this._image) {
9123			this._updateOpacity();
9124		}
9125		return this;
9126	},
9127
9128	setStyle: function (styleOpts) {
9129		if (styleOpts.opacity) {
9130			this.setOpacity(styleOpts.opacity);
9131		}
9132		return this;
9133	},
9134
9135	// @method bringToFront(): this
9136	// Brings the layer to the top of all overlays.
9137	bringToFront: function () {
9138		if (this._map) {
9139			toFront(this._image);
9140		}
9141		return this;
9142	},
9143
9144	// @method bringToBack(): this
9145	// Brings the layer to the bottom of all overlays.
9146	bringToBack: function () {
9147		if (this._map) {
9148			toBack(this._image);
9149		}
9150		return this;
9151	},
9152
9153	// @method setUrl(url: String): this
9154	// Changes the URL of the image.
9155	setUrl: function (url) {
9156		this._url = url;
9157
9158		if (this._image) {
9159			this._image.src = url;
9160		}
9161		return this;
9162	},
9163
9164	// @method setBounds(bounds: LatLngBounds): this
9165	// Update the bounds that this ImageOverlay covers
9166	setBounds: function (bounds) {
9167		this._bounds = toLatLngBounds(bounds);
9168
9169		if (this._map) {
9170			this._reset();
9171		}
9172		return this;
9173	},
9174
9175	getEvents: function () {
9176		var events = {
9177			zoom: this._reset,
9178			viewreset: this._reset
9179		};
9180
9181		if (this._zoomAnimated) {
9182			events.zoomanim = this._animateZoom;
9183		}
9184
9185		return events;
9186	},
9187
9188	// @method setZIndex(value: Number): this
9189	// Changes the [zIndex](#imageoverlay-zindex) of the image overlay.
9190	setZIndex: function (value) {
9191		this.options.zIndex = value;
9192		this._updateZIndex();
9193		return this;
9194	},
9195
9196	// @method getBounds(): LatLngBounds
9197	// Get the bounds that this ImageOverlay covers
9198	getBounds: function () {
9199		return this._bounds;
9200	},
9201
9202	// @method getElement(): HTMLElement
9203	// Returns the instance of [`HTMLImageElement`](https://developer.mozilla.org/docs/Web/API/HTMLImageElement)
9204	// used by this overlay.
9205	getElement: function () {
9206		return this._image;
9207	},
9208
9209	_initImage: function () {
9210		var wasElementSupplied = this._url.tagName === 'IMG';
9211		var img = this._image = wasElementSupplied ? this._url : create$1('img');
9212
9213		addClass(img, 'leaflet-image-layer');
9214		if (this._zoomAnimated) { addClass(img, 'leaflet-zoom-animated'); }
9215		if (this.options.className) { addClass(img, this.options.className); }
9216
9217		img.onselectstart = falseFn;
9218		img.onmousemove = falseFn;
9219
9220		// @event load: Event
9221		// Fired when the ImageOverlay layer has loaded its image
9222		img.onload = bind(this.fire, this, 'load');
9223		img.onerror = bind(this._overlayOnError, this, 'error');
9224
9225		if (this.options.crossOrigin || this.options.crossOrigin === '') {
9226			img.crossOrigin = this.options.crossOrigin === true ? '' : this.options.crossOrigin;
9227		}
9228
9229		if (this.options.zIndex) {
9230			this._updateZIndex();
9231		}
9232
9233		if (wasElementSupplied) {
9234			this._url = img.src;
9235			return;
9236		}
9237
9238		img.src = this._url;
9239		img.alt = this.options.alt;
9240	},
9241
9242	_animateZoom: function (e) {
9243		var scale = this._map.getZoomScale(e.zoom),
9244		    offset = this._map._latLngBoundsToNewLayerBounds(this._bounds, e.zoom, e.center).min;
9245
9246		setTransform(this._image, offset, scale);
9247	},
9248
9249	_reset: function () {
9250		var image = this._image,
9251		    bounds = new Bounds(
9252		        this._map.latLngToLayerPoint(this._bounds.getNorthWest()),
9253		        this._map.latLngToLayerPoint(this._bounds.getSouthEast())),
9254		    size = bounds.getSize();
9255
9256		setPosition(image, bounds.min);
9257
9258		image.style.width  = size.x + 'px';
9259		image.style.height = size.y + 'px';
9260	},
9261
9262	_updateOpacity: function () {
9263		setOpacity(this._image, this.options.opacity);
9264	},
9265
9266	_updateZIndex: function () {
9267		if (this._image && this.options.zIndex !== undefined && this.options.zIndex !== null) {
9268			this._image.style.zIndex = this.options.zIndex;
9269		}
9270	},
9271
9272	_overlayOnError: function () {
9273		// @event error: Event
9274		// Fired when the ImageOverlay layer fails to load its image
9275		this.fire('error');
9276
9277		var errorUrl = this.options.errorOverlayUrl;
9278		if (errorUrl && this._url !== errorUrl) {
9279			this._url = errorUrl;
9280			this._image.src = errorUrl;
9281		}
9282	}
9283});
9284
9285// @factory L.imageOverlay(imageUrl: String, bounds: LatLngBounds, options?: ImageOverlay options)
9286// Instantiates an image overlay object given the URL of the image and the
9287// geographical bounds it is tied to.
9288var imageOverlay = function (url, bounds, options) {
9289	return new ImageOverlay(url, bounds, options);
9290};
9291
9292/*
9293 * @class VideoOverlay
9294 * @aka L.VideoOverlay
9295 * @inherits ImageOverlay
9296 *
9297 * Used to load and display a video player over specific bounds of the map. Extends `ImageOverlay`.
9298 *
9299 * A video overlay uses the [`<video>`](https://developer.mozilla.org/docs/Web/HTML/Element/video)
9300 * HTML5 element.
9301 *
9302 * @example
9303 *
9304 * ```js
9305 * var videoUrl = 'https://www.mapbox.com/bites/00188/patricia_nasa.webm',
9306 * 	videoBounds = [[ 32, -130], [ 13, -100]];
9307 * L.videoOverlay(videoUrl, videoBounds ).addTo(map);
9308 * ```
9309 */
9310
9311var VideoOverlay = ImageOverlay.extend({
9312
9313	// @section
9314	// @aka VideoOverlay options
9315	options: {
9316		// @option autoplay: Boolean = true
9317		// Whether the video starts playing automatically when loaded.
9318		autoplay: true,
9319
9320		// @option loop: Boolean = true
9321		// Whether the video will loop back to the beginning when played.
9322		loop: true
9323	},
9324
9325	_initImage: function () {
9326		var wasElementSupplied = this._url.tagName === 'VIDEO';
9327		var vid = this._image = wasElementSupplied ? this._url : create$1('video');
9328
9329		addClass(vid, 'leaflet-image-layer');
9330		if (this._zoomAnimated) { addClass(vid, 'leaflet-zoom-animated'); }
9331
9332		vid.onselectstart = falseFn;
9333		vid.onmousemove = falseFn;
9334
9335		// @event load: Event
9336		// Fired when the video has finished loading the first frame
9337		vid.onloadeddata = bind(this.fire, this, 'load');
9338
9339		if (wasElementSupplied) {
9340			var sourceElements = vid.getElementsByTagName('source');
9341			var sources = [];
9342			for (var j = 0; j < sourceElements.length; j++) {
9343				sources.push(sourceElements[j].src);
9344			}
9345
9346			this._url = (sourceElements.length > 0) ? sources : [vid.src];
9347			return;
9348		}
9349
9350		if (!isArray(this._url)) { this._url = [this._url]; }
9351
9352		vid.autoplay = !!this.options.autoplay;
9353		vid.loop = !!this.options.loop;
9354		for (var i = 0; i < this._url.length; i++) {
9355			var source = create$1('source');
9356			source.src = this._url[i];
9357			vid.appendChild(source);
9358		}
9359	}
9360
9361	// @method getElement(): HTMLVideoElement
9362	// Returns the instance of [`HTMLVideoElement`](https://developer.mozilla.org/docs/Web/API/HTMLVideoElement)
9363	// used by this overlay.
9364});
9365
9366
9367// @factory L.videoOverlay(video: String|Array|HTMLVideoElement, bounds: LatLngBounds, options?: VideoOverlay options)
9368// Instantiates an image overlay object given the URL of the video (or array of URLs, or even a video element) and the
9369// geographical bounds it is tied to.
9370
9371function videoOverlay(video, bounds, options) {
9372	return new VideoOverlay(video, bounds, options);
9373}
9374
9375/*
9376 * @class DivOverlay
9377 * @inherits Layer
9378 * @aka L.DivOverlay
9379 * Base model for L.Popup and L.Tooltip. Inherit from it for custom popup like plugins.
9380 */
9381
9382// @namespace DivOverlay
9383var DivOverlay = Layer.extend({
9384
9385	// @section
9386	// @aka DivOverlay options
9387	options: {
9388		// @option offset: Point = Point(0, 7)
9389		// The offset of the popup position. Useful to control the anchor
9390		// of the popup when opening it on some overlays.
9391		offset: [0, 7],
9392
9393		// @option className: String = ''
9394		// A custom CSS class name to assign to the popup.
9395		className: '',
9396
9397		// @option pane: String = 'popupPane'
9398		// `Map pane` where the popup will be added.
9399		pane: 'popupPane'
9400	},
9401
9402	initialize: function (options, source) {
9403		setOptions(this, options);
9404
9405		this._source = source;
9406	},
9407
9408	onAdd: function (map) {
9409		this._zoomAnimated = map._zoomAnimated;
9410
9411		if (!this._container) {
9412			this._initLayout();
9413		}
9414
9415		if (map._fadeAnimated) {
9416			setOpacity(this._container, 0);
9417		}
9418
9419		clearTimeout(this._removeTimeout);
9420		this.getPane().appendChild(this._container);
9421		this.update();
9422
9423		if (map._fadeAnimated) {
9424			setOpacity(this._container, 1);
9425		}
9426
9427		this.bringToFront();
9428	},
9429
9430	onRemove: function (map) {
9431		if (map._fadeAnimated) {
9432			setOpacity(this._container, 0);
9433			this._removeTimeout = setTimeout(bind(remove, undefined, this._container), 200);
9434		} else {
9435			remove(this._container);
9436		}
9437	},
9438
9439	// @namespace Popup
9440	// @method getLatLng: LatLng
9441	// Returns the geographical point of popup.
9442	getLatLng: function () {
9443		return this._latlng;
9444	},
9445
9446	// @method setLatLng(latlng: LatLng): this
9447	// Sets the geographical point where the popup will open.
9448	setLatLng: function (latlng) {
9449		this._latlng = toLatLng(latlng);
9450		if (this._map) {
9451			this._updatePosition();
9452			this._adjustPan();
9453		}
9454		return this;
9455	},
9456
9457	// @method getContent: String|HTMLElement
9458	// Returns the content of the popup.
9459	getContent: function () {
9460		return this._content;
9461	},
9462
9463	// @method setContent(htmlContent: String|HTMLElement|Function): this
vendor: 3,443 bytes, lines 9464-9593
9464	// Sets the HTML content of the popup. If a function is passed the source layer will be passed to the function. The function should return a `String` or `HTMLElement` to be used in the popup.
9465	setContent: function (content) {
9466		this._content = content;
9467		this.update();
9468		return this;
9469	},
9470
9471	// @method getElement: String|HTMLElement
9472	// Alias for [getContent()](#popup-getcontent)
9473	getElement: function () {
9474		return this._container;
9475	},
9476
9477	// @method update: null
9478	// Updates the popup content, layout and position. Useful for updating the popup after something inside changed, e.g. image loaded.
9479	update: function () {
9480		if (!this._map) { return; }
9481
9482		this._container.style.visibility = 'hidden';
9483
9484		this._updateContent();
9485		this._updateLayout();
9486		this._updatePosition();
9487
9488		this._container.style.visibility = '';
9489
9490		this._adjustPan();
9491	},
9492
9493	getEvents: function () {
9494		var events = {
9495			zoom: this._updatePosition,
9496			viewreset: this._updatePosition
9497		};
9498
9499		if (this._zoomAnimated) {
9500			events.zoomanim = this._animateZoom;
9501		}
9502		return events;
9503	},
9504
9505	// @method isOpen: Boolean
9506	// Returns `true` when the popup is visible on the map.
9507	isOpen: function () {
9508		return !!this._map && this._map.hasLayer(this);
9509	},
9510
9511	// @method bringToFront: this
9512	// Brings this popup in front of other popups (in the same map pane).
9513	bringToFront: function () {
9514		if (this._map) {
9515			toFront(this._container);
9516		}
9517		return this;
9518	},
9519
9520	// @method bringToBack: this
9521	// Brings this popup to the back of other popups (in the same map pane).
9522	bringToBack: function () {
9523		if (this._map) {
9524			toBack(this._container);
9525		}
9526		return this;
9527	},
9528
9529	_updateContent: function () {
9530		if (!this._content) { return; }
9531
9532		var node = this._contentNode;
9533		var content = (typeof this._content === 'function') ? this._content(this._source || this) : this._content;
9534
9535		if (typeof content === 'string') {
9536			node.innerHTML = content;
9537		} else {
9538			while (node.hasChildNodes()) {
9539				node.removeChild(node.firstChild);
9540			}
9541			node.appendChild(content);
9542		}
9543		this.fire('contentupdate');
9544	},
9545
9546	_updatePosition: function () {
9547		if (!this._map) { return; }
9548
9549		var pos = this._map.latLngToLayerPoint(this._latlng),
9550		    offset = toPoint(this.options.offset),
9551		    anchor = this._getAnchor();
9552
9553		if (this._zoomAnimated) {
9554			setPosition(this._container, pos.add(anchor));
9555		} else {
9556			offset = offset.add(pos).add(anchor);
9557		}
9558
9559		var bottom = this._containerBottom = -offset.y,
9560		    left = this._containerLeft = -Math.round(this._containerWidth / 2) + offset.x;
9561
9562		// bottom position the popup in case the height of the popup changes (images loading etc)
9563		this._container.style.bottom = bottom + 'px';
9564		this._container.style.left = left + 'px';
9565	},
9566
9567	_getAnchor: function () {
9568		return [0, 0];
9569	}
9570
9571});
9572
9573/*
9574 * @class Popup
9575 * @inherits DivOverlay
9576 * @aka L.Popup
9577 * Used to open popups in certain places of the map. Use [Map.openPopup](#map-openpopup) to
9578 * open popups while making sure that only one popup is open at one time
9579 * (recommended for usability), or use [Map.addLayer](#map-addlayer) to open as many as you want.
9580 *
9581 * @example
9582 *
9583 * If you want to just bind a popup to marker click and then open it, it's really easy:
9584 *
9585 * ```js
9586 * marker.bindPopup(popupContent).openPopup();
9587 * ```
9588 * Path overlays like polylines also have a `bindPopup` method.
9589 * Here's a more complicated way to open a popup on a map:
9590 *
9591 * ```js
9592 * var popup = L.popup()
9593 * 	.setLatLng(latlng)
9594 * 	.setContent('<p>Hello world!<br />This is a nice popup.</p>')
9595 * 	.openOn(map);
9596 * ```
9597 */
9598
9599
9600// @namespace Popup
9601var Popup = DivOverlay.extend({
9602
9603	// @section
9604	// @aka Popup options
9605	options: {
9606		// @option maxWidth: Number = 300
9607		// Max width of the popup, in pixels.
9608		maxWidth: 300,
9609
9610		// @option minWidth: Number = 50
9611		// Min width of the popup, in pixels.
9612		minWidth: 50,
9613
9614		// @option maxHeight: Number = null
9615		// If set, creates a scrollable container of the given height
9616		// inside a popup if its content exceeds it.
9617		maxHeight: null,
9618
9619		// @option autoPan: Boolean = true
9620		// Set it to `false` if you don't want the map to do panning animation
9621		// to fit the opened popup.
9622		autoPan: true,
9623
9624		// @option autoPanPaddingTopLeft: Point = null
9625		// The margin between the popup and the top left corner of the map
9626		// view after autopanning was performed.
9627		autoPanPaddingTopLeft: null,
9628
9629		// @option autoPanPaddingBottomRight: Point = null
9630		// The margin between the popup and the bottom right corner of the map
9631		// view after autopanning was performed.
9632		autoPanPaddingBottomRight: null,
9633
9634		// @option autoPanPadding: Point = Point(5, 5)
9635		// Equivalent of setting both top left and bottom right autopan padding to the same value.
9636		autoPanPadding: [5, 5],
9637
9638		// @option keepInView: Boolean = false
9639		// Set it to `true` if you want to prevent users from panning the popup
9640		// off of the screen while it is open.
9641		keepInView: false,
9642
9643		// @option closeButton: Boolean = true
9644		// Controls the presence of a close button in the popup.
9645		closeButton: true,
9646
9647		// @option autoClose: Boolean = true
9648		// Set it to `false` if you want to override the default behavior of
9649		// the popup closing when another popup is opened.
9650		autoClose: true,
9651
9652		// @option closeOnEscapeKey: Boolean = true
9653		// Set it to `false` if you want to override the default behavior of
9654		// the ESC key for closing of the popup.
9655		closeOnEscapeKey: true,
9656
9657		// @option closeOnClick: Boolean = *
9658		// Set it if you want to override the default behavior of the popup closing when user clicks
9659		// on the map. Defaults to the map's [`closePopupOnClick`](#map-closepopuponclick) option.
9660
9661		// @option className: String = ''
9662		// A custom CSS class name to assign to the popup.
9663		className: ''
9664	},
9665
9666	// @namespace Popup
9667	// @method openOn(map: Map): this
9668	// Adds the popup to the map and closes the previous one. The same as `map.openPopup(popup)`.
9669	openOn: function (map) {
9670		map.openPopup(this);
9671		return this;
9672	},
9673
9674	onAdd: function (map) {
9675		DivOverlay.prototype.onAdd.call(this, map);
9676
9677		// @namespace Map
9678		// @section Popup events
9679		// @event popupopen: PopupEvent
9680		// Fired when a popup is opened in the map
9681		map.fire('popupopen', {popup: this});
9682
9683		if (this._source) {
9684			// @namespace Layer
9685			// @section Popup events
9686			// @event popupopen: PopupEvent
9687			// Fired when a popup bound to this layer is opened
9688			this._source.fire('popupopen', {popup: this}, true);
9689			// For non-path layers, we toggle the popup when clicking
9690			// again the layer, so prevent the map to reopen it.
9691			if (!(this._source instanceof Path)) {
9692				this._source.on('preclick', stopPropagation);
9693			}
9694		}
9695	},
9696
9697	onRemove: function (map) {
9698		DivOverlay.prototype.onRemove.call(this, map);
9699
9700		// @namespace Map
9701		// @section Popup events
9702		// @event popupclose: PopupEvent
9703		// Fired when a popup in the map is closed
9704		map.fire('popupclose', {popup: this});
9705
9706		if (this._source) {
9707			// @namespace Layer
9708			// @section Popup events
9709			// @event popupclose: PopupEvent
9710			// Fired when a popup bound to this layer is closed
9711			this._source.fire('popupclose', {popup: this}, true);
9712			if (!(this._source instanceof Path)) {
9713				this._source.off('preclick', stopPropagation);
9714			}
9715		}
9716	},
9717
9718	getEvents: function () {
9719		var events = DivOverlay.prototype.getEvents.call(this);
9720
9721		if (this.options.closeOnClick !== undefined ? this.options.closeOnClick : this._map.options.closePopupOnClick) {
9722			events.preclick = this._close;
9723		}
9724
9725		if (this.options.keepInView) {
9726			events.moveend = this._adjustPan;
9727		}
9728
9729		return events;
9730	},
9731
9732	_close: function () {
9733		if (this._map) {
9734			this._map.closePopup(this);
9735		}
9736	},
9737
9738	_initLayout: function () {
9739		var prefix = 'leaflet-popup',
9740		    container = this._container = create$1('div',
9741			prefix + ' ' + (this.options.className || '') +
9742			' leaflet-zoom-animated');
9743
9744		var wrapper = this._wrapper = create$1('div', prefix + '-content-wrapper', container);
9745		this._contentNode = create$1('div', prefix + '-content', wrapper);
9746
9747		disableClickPropagation(wrapper);
9748		disableScrollPropagation(this._contentNode);
9749		on(wrapper, 'contextmenu', stopPropagation);
9750
9751		this._tipContainer = create$1('div', prefix + '-tip-container', container);
9752		this._tip = create$1('div', prefix + '-tip', this._tipContainer);
9753
9754		if (this.options.closeButton) {
9755			var closeButton = this._closeButton = create$1('a', prefix + '-close-button', container);
9756			closeButton.href = '#close';
9757			closeButton.innerHTML = '&#215;';
9758
9759			on(closeButton, 'click', this._onCloseButtonClick, this);
9760		}
9761	},
9762
9763	_updateLayout: function () {
9764		var container = this._contentNode,
9765		    style = container.style;
9766
9767		style.width = '';
9768		style.whiteSpace = 'nowrap';
9769
9770		var width = container.offsetWidth;
9771		width = Math.min(width, this.options.maxWidth);
9772		width = Math.max(width, this.options.minWidth);
9773
9774		style.width = (width + 1) + 'px';
9775		style.whiteSpace = '';
9776
9777		style.height = '';
9778
9779		var height = container.offsetHeight,
9780		    maxHeight = this.options.maxHeight,
9781		    scrolledClass = 'leaflet-popup-scrolled';
9782
9783		if (maxHeight && height > maxHeight) {
9784			style.height = maxHeight + 'px';
9785			addClass(container, scrolledClass);
9786		} else {
9787			removeClass(container, scrolledClass);
9788		}
9789
9790		this._containerWidth = this._container.offsetWidth;
9791	},
9792
9793	_animateZoom: function (e) {
9794		var pos = this._map._latLngToNewLayerPoint(this._latlng, e.zoom, e.center),
9795		    anchor = this._getAnchor();
9796		setPosition(this._container, pos.add(anchor));
9797	},
9798
9799	_adjustPan: function () {
9800		if (!this.options.autoPan || (this._map._panAnim && this._map._panAnim._inProgress)) { return; }
9801
9802		var map = this._map,
9803		    marginBottom = parseInt(getStyle(this._container, 'marginBottom'), 10) || 0,
9804		    containerHeight = this._container.offsetHeight + marginBottom,
9805		    containerWidth = this._containerWidth,
9806		    layerPos = new Point(this._containerLeft, -containerHeight - this._containerBottom);
9807
9808		layerPos._add(getPosition(this._container));
9809
9810		var containerPos = map.layerPointToContainerPoint(layerPos),
9811		    padding = toPoint(this.options.autoPanPadding),
9812		    paddingTL = toPoint(this.options.autoPanPaddingTopLeft || padding),
9813		    paddingBR = toPoint(this.options.autoPanPaddingBottomRight || padding),
9814		    size = map.getSize(),
9815		    dx = 0,
9816		    dy = 0;
9817
9818		if (containerPos.x + containerWidth + paddingBR.x > size.x) { // right
9819			dx = containerPos.x + containerWidth - size.x + paddingBR.x;
9820		}
9821		if (containerPos.x - dx - paddingTL.x < 0) { // left
9822			dx = containerPos.x - paddingTL.x;
9823		}
9824		if (containerPos.y + containerHeight + paddingBR.y > size.y) { // bottom
9825			dy = containerPos.y + containerHeight - size.y + paddingBR.y;
9826		}
9827		if (containerPos.y - dy - paddingTL.y < 0) { // top
9828			dy = containerPos.y - paddingTL.y;
9829		}
9830
9831		// @namespace Map
9832		// @section Popup events
9833		// @event autopanstart: Event
9834		// Fired when the map starts autopanning when opening a popup.
9835		if (dx || dy) {
9836			map
9837			    .fire('autopanstart')
9838			    .panBy([dx, dy]);
9839		}
9840	},
9841
9842	_onCloseButtonClick: function (e) {
9843		this._close();
9844		stop(e);
9845	},
9846
9847	_getAnchor: function () {
9848		// Where should we anchor the popup on the source layer?
9849		return toPoint(this._source && this._source._getPopupAnchor ? this._source._getPopupAnchor() : [0, 0]);
9850	}
9851
9852});
9853
9854// @namespace Popup
9855// @factory L.popup(options?: Popup options, source?: Layer)
9856// Instantiates a `Popup` object given an optional `options` object that describes its appearance and location and an optional `source` object that is used to tag the popup with a reference to the Layer to which it refers.
9857var popup = function (options, source) {
9858	return new Popup(options, source);
9859};
9860
9861
9862/* @namespace Map
9863 * @section Interaction Options
9864 * @option closePopupOnClick: Boolean = true
9865 * Set it to `false` if you don't want popups to close when user clicks the map.
9866 */
9867Map.mergeOptions({
9868	closePopupOnClick: true
9869});
9870
9871
9872// @namespace Map
9873// @section Methods for Layers and Controls
9874Map.include({
9875	// @method openPopup(popup: Popup): this
9876	// Opens the specified popup while closing the previously opened (to make sure only one is opened at one time for usability).
9877	// @alternative
9878	// @method openPopup(content: String|HTMLElement, latlng: LatLng, options?: Popup options): this
9879	// Creates a popup with the specified content and options and opens it in the given point on a map.
9880	openPopup: function (popup, latlng, options) {
9881		if (!(popup instanceof Popup)) {
9882			popup = new Popup(options).setContent(popup);
9883		}
9884
9885		if (latlng) {
9886			popup.setLatLng(latlng);
9887		}
9888
9889		if (this.hasLayer(popup)) {
9890			return this;
9891		}
9892
9893		if (this._popup && this._popup.options.autoClose) {
9894			this.closePopup();
9895		}
9896
9897		this._popup = popup;
9898		return this.addLayer(popup);
9899	},
9900
9901	// @method closePopup(popup?: Popup): this
9902	// Closes the popup previously opened with [openPopup](#map-openpopup) (or the given one).
9903	closePopup: function (popup) {
9904		if (!popup || popup === this._popup) {
9905			popup = this._popup;
9906			this._popup = null;
9907		}
9908		if (popup) {
9909			this.removeLayer(popup);
9910		}
9911		return this;
9912	}
9913});
9914
9915/*
9916 * @namespace Layer
9917 * @section Popup methods example
9918 *
9919 * All layers share a set of methods convenient for binding popups to it.
9920 *
9921 * ```js
9922 * var layer = L.Polygon(latlngs).bindPopup('Hi There!').addTo(map);
9923 * layer.openPopup();
9924 * layer.closePopup();
9925 * ```
9926 *
9927 * Popups will also be automatically opened when the layer is clicked on and closed when the layer is removed from the map or another popup is opened.
9928 */
9929
9930// @section Popup methods
9931Layer.include({
9932
9933	// @method bindPopup(content: String|HTMLElement|Function|Popup, options?: Popup options): this
9934	// Binds a popup to the layer with the passed `content` and sets up the
9935	// necessary event listeners. If a `Function` is passed it will receive
9936	// the layer as the first argument and should return a `String` or `HTMLElement`.
9937	bindPopup: function (content, options) {
9938
9939		if (content instanceof Popup) {
9940			setOptions(content, options);
9941			this._popup = content;
9942			content._source = this;
9943		} else {
9944			if (!this._popup || options) {
9945				this._popup = new Popup(options, this);
9946			}
9947			this._popup.setContent(content);
9948		}
9949
9950		if (!this._popupHandlersAdded) {
9951			this.on({
9952				click: this._openPopup,
9953				keypress: this._onKeyPress,
9954				remove: this.closePopup,
9955				move: this._movePopup
9956			});
9957			this._popupHandlersAdded = true;
9958		}
9959
9960		return this;
9961	},
9962
9963	// @method unbindPopup(): this
9964	// Removes the popup previously bound with `bindPopup`.
9965	unbindPopup: function () {
9966		if (this._popup) {
9967			this.off({
9968				click: this._openPopup,
9969				keypress: this._onKeyPress,
9970				remove: this.closePopup,
9971				move: this._movePopup
9972			});
9973			this._popupHandlersAdded = false;
9974			this._popup = null;
9975		}
9976		return this;
9977	},
9978
9979	// @method openPopup(latlng?: LatLng): this
9980	// Opens the bound popup at the specified `latlng` or at the default popup anchor if no `latlng` is passed.
9981	openPopup: function (layer, latlng) {
9982		if (!(layer instanceof Layer)) {
9983			latlng = layer;
9984			layer = this;
9985		}
9986
9987		if (layer instanceof FeatureGroup) {
9988			for (var id in this._layers) {
9989				layer = this._layers[id];
9990				break;
9991			}
9992		}
9993
9994		if (!latlng) {
9995			latlng = layer.getCenter ? layer.getCenter() : layer.getLatLng();
9996		}
9997
9998		if (this._popup && this._map) {
9999			// set popup source to this layer
10000			this._popup._source = layer;
10001
10002			// update the popup (content, layout, ect...)
10003			this._popup.update();
10004
10005			// open the popup on the map
10006			this._map.openPopup(this._popup, latlng);
10007		}
10008
10009		return this;
10010	},
10011
10012	// @method closePopup(): this
10013	// Closes the popup bound to this layer if it is open.
10014	closePopup: function () {
10015		if (this._popup) {
10016			this._popup._close();
10017		}
10018		return this;
10019	},
10020
10021	// @method togglePopup(): this
10022	// Opens or closes the popup bound to this layer depending on its current state.
10023	togglePopup: function (target) {
10024		if (this._popup) {
10025			if (this._popup._map) {
10026				this.closePopup();
10027			} else {
10028				this.openPopup(target);
10029			}
10030		}
10031		return this;
10032	},
10033
10034	// @method isPopupOpen(): boolean
10035	// Returns `true` if the popup bound to this layer is currently open.
10036	isPopupOpen: function () {
10037		return (this._popup ? this._popup.isOpen() : false);
10038	},
10039
10040	// @method setPopupContent(content: String|HTMLElement|Popup): this
10041	// Sets the content of the popup bound to this layer.
10042	setPopupContent: function (content) {
10043		if (this._popup) {
10044			this._popup.setContent(content);
10045		}
10046		return this;
10047	},
10048
10049	// @method getPopup(): Popup
10050	// Returns the popup bound to this layer.
10051	getPopup: function () {
10052		return this._popup;
10053	},
10054
10055	_openPopup: function (e) {
10056		var layer = e.layer || e.target;
10057
10058		if (!this._popup) {
10059			return;
10060		}
10061
10062		if (!this._map) {
10063			return;
10064		}
10065
10066		// prevent map click
10067		stop(e);
10068
10069		// if this inherits from Path its a vector and we can just
10070		// open the popup at the new location
10071		if (layer instanceof Path) {
10072			this.openPopup(e.layer || e.target, e.latlng);
10073			return;
10074		}
10075
10076		// otherwise treat it like a marker and figure out
10077		// if we should toggle it open/closed
10078		if (this._map.hasLayer(this._popup) && this._popup._source === layer) {
10079			this.closePopup();
10080		} else {
10081			this.openPopup(layer, e.latlng);
10082		}
10083	},
10084
10085	_movePopup: function (e) {
10086		this._popup.setLatLng(e.latlng);
10087	},
10088
10089	_onKeyPress: function (e) {
10090		if (e.originalEvent.keyCode === 13) {
10091			this._openPopup(e);
10092		}
10093	}
10094});
10095
10096/*
10097 * @class Tooltip
10098 * @inherits DivOverlay
10099 * @aka L.Tooltip
10100 * Used to display small texts on top of map layers.
10101 *
10102 * @example
10103 *
10104 * ```js
10105 * marker.bindTooltip("my tooltip text").openTooltip();
10106 * ```
10107 * Note about tooltip offset. Leaflet takes two options in consideration
10108 * for computing tooltip offsetting:
10109 * - the `offset` Tooltip option: it defaults to [0, 0], and it's specific to one tooltip.
10110 *   Add a positive x offset to move the tooltip to the right, and a positive y offset to
10111 *   move it to the bottom. Negatives will move to the left and top.
10112 * - the `tooltipAnchor` Icon option: this will only be considered for Marker. You
10113 *   should adapt this value if you use a custom icon.
10114 */
10115
10116
10117// @namespace Tooltip
10118var Tooltip = DivOverlay.extend({
10119
10120	// @section
10121	// @aka Tooltip options
10122	options: {
10123		// @option pane: String = 'tooltipPane'
10124		// `Map pane` where the tooltip will be added.
10125		pane: 'tooltipPane',
10126
10127		// @option offset: Point = Point(0, 0)
10128		// Optional offset of the tooltip position.
10129		offset: [0, 0],
10130
10131		// @option direction: String = 'auto'
10132		// Direction where to open the tooltip. Possible values are: `right`, `left`,
10133		// `top`, `bottom`, `center`, `auto`.
10134		// `auto` will dynamically switch between `right` and `left` according to the tooltip
10135		// position on the map.
10136		direction: 'auto',
10137
10138		// @option permanent: Boolean = false
10139		// Whether to open the tooltip permanently or only on mouseover.
10140		permanent: false,
10141
10142		// @option sticky: Boolean = false
10143		// If true, the tooltip will follow the mouse instead of being fixed at the feature center.
10144		sticky: false,
10145
10146		// @option interactive: Boolean = false
10147		// If true, the tooltip will listen to the feature events.
10148		interactive: false,
10149
10150		// @option opacity: Number = 0.9
10151		// Tooltip container opacity.
10152		opacity: 0.9
10153	},
10154
10155	onAdd: function (map) {
10156		DivOverlay.prototype.onAdd.call(this, map);
10157		this.setOpacity(this.options.opacity);
10158
10159		// @namespace Map
10160		// @section Tooltip events
10161		// @event tooltipopen: TooltipEvent
10162		// Fired when a tooltip is opened in the map.
10163		map.fire('tooltipopen', {tooltip: this});
10164
10165		if (this._source) {
10166			// @namespace Layer
10167			// @section Tooltip events
10168			// @event tooltipopen: TooltipEvent
10169			// Fired when a tooltip bound to this layer is opened.
10170			this._source.fire('tooltipopen', {tooltip: this}, true);
10171		}
10172	},
10173
10174	onRemove: function (map) {
10175		DivOverlay.prototype.onRemove.call(this, map);
10176
10177		// @namespace Map
10178		// @section Tooltip events
10179		// @event tooltipclose: TooltipEvent
10180		// Fired when a tooltip in the map is closed.
10181		map.fire('tooltipclose', {tooltip: this});
10182
10183		if (this._source) {
10184			// @namespace Layer
10185			// @section Tooltip events
10186			// @event tooltipclose: TooltipEvent
10187			// Fired when a tooltip bound to this layer is closed.
10188			this._source.fire('tooltipclose', {tooltip: this}, true);
10189		}
10190	},
10191
10192	getEvents: function () {
10193		var events = DivOverlay.prototype.getEvents.call(this);
10194
10195		if (touch && !this.options.permanent) {
10196			events.preclick = this._close;
10197		}
10198
10199		return events;
10200	},
10201
10202	_close: function () {
10203		if (this._map) {
10204			this._map.closeTooltip(this);
10205		}
10206	},
10207
10208	_initLayout: function () {
10209		var prefix = 'leaflet-tooltip',
10210		    className = prefix + ' ' + (this.options.className || '') + ' leaflet-zoom-' + (this._zoomAnimated ? 'animated' : 'hide');
10211
10212		this._contentNode = this._container = create$1('div', className);
10213	},
10214
10215	_updateLayout: function () {},
10216
10217	_adjustPan: function () {},
10218
10219	_setPosition: function (pos) {
10220		var map = this._map,
10221		    container = this._container,
10222		    centerPoint = map.latLngToContainerPoint(map.getCenter()),
10223		    tooltipPoint = map.layerPointToContainerPoint(pos),
10224		    direction = this.options.direction,
10225		    tooltipWidth = container.offsetWidth,
10226		    tooltipHeight = container.offsetHeight,
10227		    offset = toPoint(this.options.offset),
10228		    anchor = this._getAnchor();
10229
10230		if (direction === 'top') {
10231			pos = pos.add(toPoint(-tooltipWidth / 2 + offset.x, -tooltipHeight + offset.y + anchor.y, true));
10232		} else if (direction === 'bottom') {
10233			pos = pos.subtract(toPoint(tooltipWidth / 2 - offset.x, -offset.y, true));
10234		} else if (direction === 'center') {
10235			pos = pos.subtract(toPoint(tooltipWidth / 2 + offset.x, tooltipHeight / 2 - anchor.y + offset.y, true));
10236		} else if (direction === 'right' || direction === 'auto' && tooltipPoint.x < centerPoint.x) {
10237			direction = 'right';
10238			pos = pos.add(toPoint(offset.x + anchor.x, anchor.y - tooltipHeight / 2 + offset.y, true));
10239		} else {
10240			direction = 'left';
10241			pos = pos.subtract(toPoint(tooltipWidth + anchor.x - offset.x, tooltipHeight / 2 - anchor.y - offset.y, true));
10242		}
10243
10244		removeClass(container, 'leaflet-tooltip-right');
10245		removeClass(container, 'leaflet-tooltip-left');
10246		removeClass(container, 'leaflet-tooltip-top');
10247		removeClass(container, 'leaflet-tooltip-bottom');
10248		addClass(container, 'leaflet-tooltip-' + direction);
10249		setPosition(container, pos);
10250	},
10251
10252	_updatePosition: function () {
10253		var pos = this._map.latLngToLayerPoint(this._latlng);
10254		this._setPosition(pos);
10255	},
10256
10257	setOpacity: function (opacity) {
10258		this.options.opacity = opacity;
10259
10260		if (this._container) {
10261			setOpacity(this._container, opacity);
10262		}
10263	},
10264
10265	_animateZoom: function (e) {
10266		var pos = this._map._latLngToNewLayerPoint(this._latlng, e.zoom, e.center);
10267		this._setPosition(pos);
10268	},
10269
10270	_getAnchor: function () {
10271		// Where should we anchor the tooltip on the source layer?
10272		return toPoint(this._source && this._source._getTooltipAnchor && !this.options.sticky ? this._source._getTooltipAnchor() : [0, 0]);
10273	}
10274
10275});
10276
10277// @namespace Tooltip
10278// @factory L.tooltip(options?: Tooltip options, source?: Layer)
10279// Instantiates a Tooltip object given an optional `options` object that describes its appearance and location and an optional `source` object that is used to tag the tooltip with a reference to the Layer to which it refers.
10280var tooltip = function (options, source) {
10281	return new Tooltip(options, source);
10282};
10283
10284// @namespace Map
10285// @section Methods for Layers and Controls
10286Map.include({
10287
10288	// @method openTooltip(tooltip: Tooltip): this
10289	// Opens the specified tooltip.
10290	// @alternative
10291	// @method openTooltip(content: String|HTMLElement, latlng: LatLng, options?: Tooltip options): this
10292	// Creates a tooltip with the specified content and options and open it.
10293	openTooltip: function (tooltip, latlng, options) {
10294		if (!(tooltip instanceof Tooltip)) {
10295			tooltip = new Tooltip(options).setContent(tooltip);
10296		}
10297
10298		if (latlng) {
10299			tooltip.setLatLng(latlng);
10300		}
10301
10302		if (this.hasLayer(tooltip)) {
10303			return this;
10304		}
10305
10306		return this.addLayer(tooltip);
10307	},
10308
10309	// @method closeTooltip(tooltip?: Tooltip): this
10310	// Closes the tooltip given as parameter.
10311	closeTooltip: function (tooltip) {
10312		if (tooltip) {
10313			this.removeLayer(tooltip);
10314		}
10315		return this;
10316	}
10317
10318});
10319
10320/*
10321 * @namespace Layer
10322 * @section Tooltip methods example
10323 *
10324 * All layers share a set of methods convenient for binding tooltips to it.
10325 *
10326 * ```js
10327 * var layer = L.Polygon(latlngs).bindTooltip('Hi There!').addTo(map);
10328 * layer.openTooltip();
10329 * layer.closeTooltip();
10330 * ```
10331 */
10332
10333// @section Tooltip methods
10334Layer.include({
10335
10336	// @method bindTooltip(content: String|HTMLElement|Function|Tooltip, options?: Tooltip options): this
10337	// Binds a tooltip to the layer with the passed `content` and sets up the
10338	// necessary event listeners. If a `Function` is passed it will receive
10339	// the layer as the first argument and should return a `String` or `HTMLElement`.
10340	bindTooltip: function (content, options) {
10341
10342		if (content instanceof Tooltip) {
10343			setOptions(content, options);
10344			this._tooltip = content;
10345			content._source = this;
10346		} else {
10347			if (!this._tooltip || options) {
10348				this._tooltip = new Tooltip(options, this);
10349			}
10350			this._tooltip.setContent(content);
10351
10352		}
10353
10354		this._initTooltipInteractions();
10355
10356		if (this._tooltip.options.permanent && this._map && this._map.hasLayer(this)) {
10357			this.openTooltip();
10358		}
10359
10360		return this;
10361	},
10362
10363	// @method unbindTooltip(): this
10364	// Removes the tooltip previously bound with `bindTooltip`.
10365	unbindTooltip: function () {
10366		if (this._tooltip) {
10367			this._initTooltipInteractions(true);
10368			this.closeTooltip();
10369			this._tooltip = null;
10370		}
10371		return this;
10372	},
10373
10374	_initTooltipInteractions: function (remove$$1) {
10375		if (!remove$$1 && this._tooltipHandlersAdded) { return; }
10376		var onOff = remove$$1 ? 'off' : 'on',
10377		    events = {
10378			remove: this.closeTooltip,
10379			move: this._moveTooltip
10380		    };
10381		if (!this._tooltip.options.permanent) {
10382			events.mouseover = this._openTooltip;
10383			events.mouseout = this.closeTooltip;
10384			if (this._tooltip.options.sticky) {
10385				events.mousemove = this._moveTooltip;
10386			}
10387			if (touch) {
10388				events.click = this._openTooltip;
10389			}
10390		} else {
10391			events.add = this._openTooltip;
10392		}
10393		this[onOff](events);
10394		this._tooltipHandlersAdded = !remove$$1;
10395	},
10396
10397	// @method openTooltip(latlng?: LatLng): this
10398	// Opens the bound tooltip at the specified `latlng` or at the default tooltip anchor if no `latlng` is passed.
10399	openTooltip: function (layer, latlng) {
10400		if (!(layer instanceof Layer)) {
10401			latlng = layer;
10402			layer = this;
10403		}
10404
10405		if (layer instanceof FeatureGroup) {
10406			for (var id in this._layers) {
10407				layer = this._layers[id];
10408				break;
10409			}
10410		}
10411
10412		if (!latlng) {
10413			latlng = layer.getCenter ? layer.getCenter() : layer.getLatLng();
10414		}
10415
10416		if (this._tooltip && this._map) {
10417
10418			// set tooltip source to this layer
10419			this._tooltip._source = layer;
10420
10421			// update the tooltip (content, layout, ect...)
10422			this._tooltip.update();
10423
10424			// open the tooltip on the map
10425			this._map.openTooltip(this._tooltip, latlng);
10426
10427			// Tooltip container may not be defined if not permanent and never
10428			// opened.
10429			if (this._tooltip.options.interactive && this._tooltip._container) {
10430				addClass(this._tooltip._container, 'leaflet-clickable');
10431				this.addInteractiveTarget(this._tooltip._container);
10432			}
10433		}
10434
10435		return this;
10436	},
10437
10438	// @method closeTooltip(): this
10439	// Closes the tooltip bound to this layer if it is open.
10440	closeTooltip: function () {
10441		if (this._tooltip) {
10442			this._tooltip._close();
10443			if (this._tooltip.options.interactive && this._tooltip._container) {
10444				removeClass(this._tooltip._container, 'leaflet-clickable');
10445				this.removeInteractiveTarget(this._tooltip._container);
10446			}
10447		}
10448		return this;
10449	},
10450
10451	// @method toggleTooltip(): this
10452	// Opens or closes the tooltip bound to this layer depending on its current state.
10453	toggleTooltip: function (target) {
10454		if (this._tooltip) {
10455			if (this._tooltip._map) {
10456				this.closeTooltip();
10457			} else {
10458				this.openTooltip(target);
10459			}
10460		}
10461		return this;
10462	},
10463
10464	// @method isTooltipOpen(): boolean
10465	// Returns `true` if the tooltip bound to this layer is currently open.
10466	isTooltipOpen: function () {
10467		return this._tooltip.isOpen();
10468	},
10469
10470	// @method setTooltipContent(content: String|HTMLElement|Tooltip): this
10471	// Sets the content of the tooltip bound to this layer.
10472	setTooltipContent: function (content) {
10473		if (this._tooltip) {
10474			this._tooltip.setContent(content);
10475		}
10476		return this;
10477	},
10478
10479	// @method getTooltip(): Tooltip
10480	// Returns the tooltip bound to this layer.
10481	getTooltip: function () {
10482		return this._tooltip;
10483	},
10484
10485	_openTooltip: function (e) {
10486		var layer = e.layer || e.target;
10487
10488		if (!this._tooltip || !this._map) {
10489			return;
10490		}
10491		this.openTooltip(layer, this._tooltip.options.sticky ? e.latlng : undefined);
10492	},
10493
10494	_moveTooltip: function (e) {
10495		var latlng = e.latlng, containerPoint, layerPoint;
10496		if (this._tooltip.options.sticky && e.originalEvent) {
10497			containerPoint = this._map.mouseEventToContainerPoint(e.originalEvent);
10498			layerPoint = this._map.containerPointToLayerPoint(containerPoint);
10499			latlng = this._map.layerPointToLatLng(layerPoint);
10500		}
10501		this._tooltip.setLatLng(latlng);
10502	}
10503});
10504
10505/*
10506 * @class DivIcon
10507 * @aka L.DivIcon
10508 * @inherits Icon
10509 *
10510 * Represents a lightweight icon for markers that uses a simple `<div>`
10511 * element instead of an image. Inherits from `Icon` but ignores the `iconUrl` and shadow options.
10512 *
10513 * @example
10514 * ```js
10515 * var myIcon = L.divIcon({className: 'my-div-icon'});
10516 * // you can set .my-div-icon styles in CSS
10517 *
10518 * L.marker([50.505, 30.57], {icon: myIcon}).addTo(map);
10519 * ```
10520 *
10521 * By default, it has a 'leaflet-div-icon' CSS class and is styled as a little white square with a shadow.
10522 */
10523
10524var DivIcon = Icon.extend({
10525	options: {
10526		// @section
10527		// @aka DivIcon options
10528		iconSize: [12, 12], // also can be set through CSS
10529
10530		// iconAnchor: (Point),
10531		// popupAnchor: (Point),
10532
10533		// @option html: String = ''
10534		// Custom HTML code to put inside the div element, empty by default.
10535		html: false,
10536
10537		// @option bgPos: Point = [0, 0]
10538		// Optional relative position of the background, in pixels
10539		bgPos: null,
10540
10541		className: 'leaflet-div-icon'
10542	},
10543
10544	createIcon: function (oldIcon) {
10545		var div = (oldIcon && oldIcon.tagName === 'DIV') ? oldIcon : document.createElement('div'),
10546		    options = this.options;
10547
10548		div.innerHTML = options.html !== false ? options.html : '';
10549
10550		if (options.bgPos) {
10551			var bgPos = toPoint(options.bgPos);
10552			div.style.backgroundPosition = (-bgPos.x) + 'px ' + (-bgPos.y) + 'px';
10553		}
10554		this._setIconStyles(div, 'icon');
10555
10556		return div;
10557	},
10558
10559	createShadow: function () {
10560		return null;
10561	}
10562});
10563
10564// @factory L.divIcon(options: DivIcon options)
10565// Creates a `DivIcon` instance with the given options.
10566function divIcon(options) {
10567	return new DivIcon(options);
10568}
10569
10570Icon.Default = IconDefault;
10571
10572/*
10573 * @class GridLayer
10574 * @inherits Layer
10575 * @aka L.GridLayer
10576 *
10577 * Generic class for handling a tiled grid of HTML elements. This is the base class for all tile layers and replaces `TileLayer.Canvas`.
10578 * GridLayer can be extended to create a tiled grid of HTML elements like `<canvas>`, `<img>` or `<div>`. GridLayer will handle creating and animating these DOM elements for you.
10579 *
10580 *
10581 * @section Synchronous usage
10582 * @example
10583 *
10584 * To create a custom layer, extend GridLayer and implement the `createTile()` method, which will be passed a `Point` object with the `x`, `y`, and `z` (zoom level) coordinates to draw your tile.
10585 *
10586 * ```js
10587 * var CanvasLayer = L.GridLayer.extend({
10588 *     createTile: function(coords){
10589 *         // create a <canvas> element for drawing
10590 *         var tile = L.DomUtil.create('canvas', 'leaflet-tile');
10591 *
10592 *         // setup tile width and height according to the options
10593 *         var size = this.getTileSize();
10594 *         tile.width = size.x;
10595 *         tile.height = size.y;
10596 *
10597 *         // get a canvas context and draw something on it using coords.x, coords.y and coords.z
10598 *         var ctx = tile.getContext('2d');
10599 *
10600 *         // return the tile so it can be rendered on screen
10601 *         return tile;
10602 *     }
10603 * });
10604 * ```
10605 *
10606 * @section Asynchronous usage
10607 * @example
10608 *
10609 * Tile creation can also be asynchronous, this is useful when using a third-party drawing library. Once the tile is finished drawing it can be passed to the `done()` callback.
10610 *
10611 * ```js
10612 * var CanvasLayer = L.GridLayer.extend({
10613 *     createTile: function(coords, done){
10614 *         var error;
10615 *
10616 *         // create a <canvas> element for drawing
10617 *         var tile = L.DomUtil.create('canvas', 'leaflet-tile');
10618 *
10619 *         // setup tile width and height according to the options
10620 *         var size = this.getTileSize();
10621 *         tile.width = size.x;
10622 *         tile.height = size.y;
10623 *
10624 *         // draw something asynchronously and pass the tile to the done() callback
10625 *         setTimeout(function() {
10626 *             done(error, tile);
10627 *         }, 1000);
10628 *
10629 *         return tile;
10630 *     }
10631 * });
10632 * ```
10633 *
10634 * @section
10635 */
10636
10637
10638var GridLayer = Layer.extend({
10639
10640	// @section
10641	// @aka GridLayer options
10642	options: {
vendor: 44,535 bytes, lines 10643-12272
10643		// @option tileSize: Number|Point = 256
10644		// Width and height of tiles in the grid. Use a number if width and height are equal, or `L.point(width, height)` otherwise.
10645		tileSize: 256,
10646
10647		// @option opacity: Number = 1.0
10648		// Opacity of the tiles. Can be used in the `createTile()` function.
10649		opacity: 1,
10650
10651		// @option updateWhenIdle: Boolean = (depends)
10652		// Load new tiles only when panning ends.
10653		// `true` by default on mobile browsers, in order to avoid too many requests and keep smooth navigation.
10654		// `false` otherwise in order to display new tiles _during_ panning, since it is easy to pan outside the
10655		// [`keepBuffer`](#gridlayer-keepbuffer) option in desktop browsers.
10656		updateWhenIdle: mobile,
10657
10658		// @option updateWhenZooming: Boolean = true
10659		// By default, a smooth zoom animation (during a [touch zoom](#map-touchzoom) or a [`flyTo()`](#map-flyto)) will update grid layers every integer zoom level. Setting this option to `false` will update the grid layer only when the smooth animation ends.
10660		updateWhenZooming: true,
10661
10662		// @option updateInterval: Number = 200
10663		// Tiles will not update more than once every `updateInterval` milliseconds when panning.
10664		updateInterval: 200,
10665
10666		// @option zIndex: Number = 1
10667		// The explicit zIndex of the tile layer.
10668		zIndex: 1,
10669
10670		// @option bounds: LatLngBounds = undefined
10671		// If set, tiles will only be loaded inside the set `LatLngBounds`.
10672		bounds: null,
10673
10674		// @option minZoom: Number = 0
10675		// The minimum zoom level down to which this layer will be displayed (inclusive).
10676		minZoom: 0,
10677
10678		// @option maxZoom: Number = undefined
10679		// The maximum zoom level up to which this layer will be displayed (inclusive).
10680		maxZoom: undefined,
10681
10682		// @option maxNativeZoom: Number = undefined
10683		// Maximum zoom number the tile source has available. If it is specified,
10684		// the tiles on all zoom levels higher than `maxNativeZoom` will be loaded
10685		// from `maxNativeZoom` level and auto-scaled.
10686		maxNativeZoom: undefined,
10687
10688		// @option minNativeZoom: Number = undefined
10689		// Minimum zoom number the tile source has available. If it is specified,
10690		// the tiles on all zoom levels lower than `minNativeZoom` will be loaded
10691		// from `minNativeZoom` level and auto-scaled.
10692		minNativeZoom: undefined,
10693
10694		// @option noWrap: Boolean = false
10695		// Whether the layer is wrapped around the antimeridian. If `true`, the
10696		// GridLayer will only be displayed once at low zoom levels. Has no
10697		// effect when the [map CRS](#map-crs) doesn't wrap around. Can be used
10698		// in combination with [`bounds`](#gridlayer-bounds) to prevent requesting
10699		// tiles outside the CRS limits.
10700		noWrap: false,
10701
10702		// @option pane: String = 'tilePane'
10703		// `Map pane` where the grid layer will be added.
10704		pane: 'tilePane',
10705
10706		// @option className: String = ''
10707		// A custom class name to assign to the tile layer. Empty by default.
10708		className: '',
10709
10710		// @option keepBuffer: Number = 2
10711		// When panning the map, keep this many rows and columns of tiles before unloading them.
10712		keepBuffer: 2
10713	},
10714
10715	initialize: function (options) {
10716		setOptions(this, options);
10717	},
10718
10719	onAdd: function () {
10720		this._initContainer();
10721
10722		this._levels = {};
10723		this._tiles = {};
10724
10725		this._resetView();
10726		this._update();
10727	},
10728
10729	beforeAdd: function (map) {
10730		map._addZoomLimit(this);
10731	},
10732
10733	onRemove: function (map) {
10734		this._removeAllTiles();
10735		remove(this._container);
10736		map._removeZoomLimit(this);
10737		this._container = null;
10738		this._tileZoom = undefined;
10739	},
10740
10741	// @method bringToFront: this
10742	// Brings the tile layer to the top of all tile layers.
10743	bringToFront: function () {
10744		if (this._map) {
10745			toFront(this._container);
10746			this._setAutoZIndex(Math.max);
10747		}
10748		return this;
10749	},
10750
10751	// @method bringToBack: this
10752	// Brings the tile layer to the bottom of all tile layers.
10753	bringToBack: function () {
10754		if (this._map) {
10755			toBack(this._container);
10756			this._setAutoZIndex(Math.min);
10757		}
10758		return this;
10759	},
10760
10761	// @method getContainer: HTMLElement
10762	// Returns the HTML element that contains the tiles for this layer.
10763	getContainer: function () {
10764		return this._container;
10765	},
10766
10767	// @method setOpacity(opacity: Number): this
10768	// Changes the [opacity](#gridlayer-opacity) of the grid layer.
10769	setOpacity: function (opacity) {
10770		this.options.opacity = opacity;
10771		this._updateOpacity();
10772		return this;
10773	},
10774
10775	// @method setZIndex(zIndex: Number): this
10776	// Changes the [zIndex](#gridlayer-zindex) of the grid layer.
10777	setZIndex: function (zIndex) {
10778		this.options.zIndex = zIndex;
10779		this._updateZIndex();
10780
10781		return this;
10782	},
10783
10784	// @method isLoading: Boolean
10785	// Returns `true` if any tile in the grid layer has not finished loading.
10786	isLoading: function () {
10787		return this._loading;
10788	},
10789
10790	// @method redraw: this
10791	// Causes the layer to clear all the tiles and request them again.
10792	redraw: function () {
10793		if (this._map) {
10794			this._removeAllTiles();
10795			this._update();
10796		}
10797		return this;
10798	},
10799
10800	getEvents: function () {
10801		var events = {
10802			viewprereset: this._invalidateAll,
10803			viewreset: this._resetView,
10804			zoom: this._resetView,
10805			moveend: this._onMoveEnd
10806		};
10807
10808		if (!this.options.updateWhenIdle) {
10809			// update tiles on move, but not more often than once per given interval
10810			if (!this._onMove) {
10811				this._onMove = throttle(this._onMoveEnd, this.options.updateInterval, this);
10812			}
10813
10814			events.move = this._onMove;
10815		}
10816
10817		if (this._zoomAnimated) {
10818			events.zoomanim = this._animateZoom;
10819		}
10820
10821		return events;
10822	},
10823
10824	// @section Extension methods
10825	// Layers extending `GridLayer` shall reimplement the following method.
10826	// @method createTile(coords: Object, done?: Function): HTMLElement
10827	// Called only internally, must be overridden by classes extending `GridLayer`.
10828	// Returns the `HTMLElement` corresponding to the given `coords`. If the `done` callback
10829	// is specified, it must be called when the tile has finished loading and drawing.
10830	createTile: function () {
10831		return document.createElement('div');
10832	},
10833
10834	// @section
10835	// @method getTileSize: Point
10836	// Normalizes the [tileSize option](#gridlayer-tilesize) into a point. Used by the `createTile()` method.
10837	getTileSize: function () {
10838		var s = this.options.tileSize;
10839		return s instanceof Point ? s : new Point(s, s);
10840	},
10841
10842	_updateZIndex: function () {
10843		if (this._container && this.options.zIndex !== undefined && this.options.zIndex !== null) {
10844			this._container.style.zIndex = this.options.zIndex;
10845		}
10846	},
10847
10848	_setAutoZIndex: function (compare) {
10849		// go through all other layers of the same pane, set zIndex to max + 1 (front) or min - 1 (back)
10850
10851		var layers = this.getPane().children,
10852		    edgeZIndex = -compare(-Infinity, Infinity); // -Infinity for max, Infinity for min
10853
10854		for (var i = 0, len = layers.length, zIndex; i < len; i++) {
10855
10856			zIndex = layers[i].style.zIndex;
10857
10858			if (layers[i] !== this._container && zIndex) {
10859				edgeZIndex = compare(edgeZIndex, +zIndex);
10860			}
10861		}
10862
10863		if (isFinite(edgeZIndex)) {
10864			this.options.zIndex = edgeZIndex + compare(-1, 1);
10865			this._updateZIndex();
10866		}
10867	},
10868
10869	_updateOpacity: function () {
10870		if (!this._map) { return; }
10871
10872		// IE doesn't inherit filter opacity properly, so we're forced to set it on tiles
10873		if (ielt9) { return; }
10874
10875		setOpacity(this._container, this.options.opacity);
10876
10877		var now = +new Date(),
10878		    nextFrame = false,
10879		    willPrune = false;
10880
10881		for (var key in this._tiles) {
10882			var tile = this._tiles[key];
10883			if (!tile.current || !tile.loaded) { continue; }
10884
10885			var fade = Math.min(1, (now - tile.loaded) / 200);
10886
10887			setOpacity(tile.el, fade);
10888			if (fade < 1) {
10889				nextFrame = true;
10890			} else {
10891				if (tile.active) {
10892					willPrune = true;
10893				} else {
10894					this._onOpaqueTile(tile);
10895				}
10896				tile.active = true;
10897			}
10898		}
10899
10900		if (willPrune && !this._noPrune) { this._pruneTiles(); }
10901
10902		if (nextFrame) {
10903			cancelAnimFrame(this._fadeFrame);
10904			this._fadeFrame = requestAnimFrame(this._updateOpacity, this);
10905		}
10906	},
10907
10908	_onOpaqueTile: falseFn,
10909
10910	_initContainer: function () {
10911		if (this._container) { return; }
10912
10913		this._container = create$1('div', 'leaflet-layer ' + (this.options.className || ''));
10914		this._updateZIndex();
10915
10916		if (this.options.opacity < 1) {
10917			this._updateOpacity();
10918		}
10919
10920		this.getPane().appendChild(this._container);
10921	},
10922
10923	_updateLevels: function () {
10924
10925		var zoom = this._tileZoom,
10926		    maxZoom = this.options.maxZoom;
10927
10928		if (zoom === undefined) { return undefined; }
10929
10930		for (var z in this._levels) {
10931			if (this._levels[z].el.children.length || z === zoom) {
10932				this._levels[z].el.style.zIndex = maxZoom - Math.abs(zoom - z);
10933				this._onUpdateLevel(z);
10934			} else {
10935				remove(this._levels[z].el);
10936				this._removeTilesAtZoom(z);
10937				this._onRemoveLevel(z);
10938				delete this._levels[z];
10939			}
10940		}
10941
10942		var level = this._levels[zoom],
10943		    map = this._map;
10944
10945		if (!level) {
10946			level = this._levels[zoom] = {};
10947
10948			level.el = create$1('div', 'leaflet-tile-container leaflet-zoom-animated', this._container);
10949			level.el.style.zIndex = maxZoom;
10950
10951			level.origin = map.project(map.unproject(map.getPixelOrigin()), zoom).round();
10952			level.zoom = zoom;
10953
10954			this._setZoomTransform(level, map.getCenter(), map.getZoom());
10955
10956			// force the browser to consider the newly added element for transition
10957			falseFn(level.el.offsetWidth);
10958
10959			this._onCreateLevel(level);
10960		}
10961
10962		this._level = level;
10963
10964		return level;
10965	},
10966
10967	_onUpdateLevel: falseFn,
10968
10969	_onRemoveLevel: falseFn,
10970
10971	_onCreateLevel: falseFn,
10972
10973	_pruneTiles: function () {
10974		if (!this._map) {
10975			return;
10976		}
10977
10978		var key, tile;
10979
10980		var zoom = this._map.getZoom();
10981		if (zoom > this.options.maxZoom ||
10982			zoom < this.options.minZoom) {
10983			this._removeAllTiles();
10984			return;
10985		}
10986
10987		for (key in this._tiles) {
10988			tile = this._tiles[key];
10989			tile.retain = tile.current;
10990		}
10991
10992		for (key in this._tiles) {
10993			tile = this._tiles[key];
10994			if (tile.current && !tile.active) {
10995				var coords = tile.coords;
10996				if (!this._retainParent(coords.x, coords.y, coords.z, coords.z - 5)) {
10997					this._retainChildren(coords.x, coords.y, coords.z, coords.z + 2);
10998				}
10999			}
11000		}
11001
11002		for (key in this._tiles) {
11003			if (!this._tiles[key].retain) {
11004				this._removeTile(key);
11005			}
11006		}
11007	},
11008
11009	_removeTilesAtZoom: function (zoom) {
11010		for (var key in this._tiles) {
11011			if (this._tiles[key].coords.z !== zoom) {
11012				continue;
11013			}
11014			this._removeTile(key);
11015		}
11016	},
11017
11018	_removeAllTiles: function () {
11019		for (var key in this._tiles) {
11020			this._removeTile(key);
11021		}
11022	},
11023
11024	_invalidateAll: function () {
11025		for (var z in this._levels) {
11026			remove(this._levels[z].el);
11027			this._onRemoveLevel(z);
11028			delete this._levels[z];
11029		}
11030		this._removeAllTiles();
11031
11032		this._tileZoom = undefined;
11033	},
11034
11035	_retainParent: function (x, y, z, minZoom) {
11036		var x2 = Math.floor(x / 2),
11037		    y2 = Math.floor(y / 2),
11038		    z2 = z - 1,
11039		    coords2 = new Point(+x2, +y2);
11040		coords2.z = +z2;
11041
11042		var key = this._tileCoordsToKey(coords2),
11043		    tile = this._tiles[key];
11044
11045		if (tile && tile.active) {
11046			tile.retain = true;
11047			return true;
11048
11049		} else if (tile && tile.loaded) {
11050			tile.retain = true;
11051		}
11052
11053		if (z2 > minZoom) {
11054			return this._retainParent(x2, y2, z2, minZoom);
11055		}
11056
11057		return false;
11058	},
11059
11060	_retainChildren: function (x, y, z, maxZoom) {
11061
11062		for (var i = 2 * x; i < 2 * x + 2; i++) {
11063			for (var j = 2 * y; j < 2 * y + 2; j++) {
11064
11065				var coords = new Point(i, j);
11066				coords.z = z + 1;
11067
11068				var key = this._tileCoordsToKey(coords),
11069				    tile = this._tiles[key];
11070
11071				if (tile && tile.active) {
11072					tile.retain = true;
11073					continue;
11074
11075				} else if (tile && tile.loaded) {
11076					tile.retain = true;
11077				}
11078
11079				if (z + 1 < maxZoom) {
11080					this._retainChildren(i, j, z + 1, maxZoom);
11081				}
11082			}
11083		}
11084	},
11085
11086	_resetView: function (e) {
11087		var animating = e && (e.pinch || e.flyTo);
11088		this._setView(this._map.getCenter(), this._map.getZoom(), animating, animating);
11089	},
11090
11091	_animateZoom: function (e) {
11092		this._setView(e.center, e.zoom, true, e.noUpdate);
11093	},
11094
11095	_clampZoom: function (zoom) {
11096		var options = this.options;
11097
11098		if (undefined !== options.minNativeZoom && zoom < options.minNativeZoom) {
11099			return options.minNativeZoom;
11100		}
11101
11102		if (undefined !== options.maxNativeZoom && options.maxNativeZoom < zoom) {
11103			return options.maxNativeZoom;
11104		}
11105
11106		return zoom;
11107	},
11108
11109	_setView: function (center, zoom, noPrune, noUpdate) {
11110		var tileZoom = this._clampZoom(Math.round(zoom));
11111		if ((this.options.maxZoom !== undefined && tileZoom > this.options.maxZoom) ||
11112		    (this.options.minZoom !== undefined && tileZoom < this.options.minZoom)) {
11113			tileZoom = undefined;
11114		}
11115
11116		var tileZoomChanged = this.options.updateWhenZooming && (tileZoom !== this._tileZoom);
11117
11118		if (!noUpdate || tileZoomChanged) {
11119
11120			this._tileZoom = tileZoom;
11121
11122			if (this._abortLoading) {
11123				this._abortLoading();
11124			}
11125
11126			this._updateLevels();
11127			this._resetGrid();
11128
11129			if (tileZoom !== undefined) {
11130				this._update(center);
11131			}
11132
11133			if (!noPrune) {
11134				this._pruneTiles();
11135			}
11136
11137			// Flag to prevent _updateOpacity from pruning tiles during
11138			// a zoom anim or a pinch gesture
11139			this._noPrune = !!noPrune;
11140		}
11141
11142		this._setZoomTransforms(center, zoom);
11143	},
11144
11145	_setZoomTransforms: function (center, zoom) {
11146		for (var i in this._levels) {
11147			this._setZoomTransform(this._levels[i], center, zoom);
11148		}
11149	},
11150
11151	_setZoomTransform: function (level, center, zoom) {
11152		var scale = this._map.getZoomScale(zoom, level.zoom),
11153		    translate = level.origin.multiplyBy(scale)
11154		        .subtract(this._map._getNewPixelOrigin(center, zoom)).round();
11155
11156		if (any3d) {
11157			setTransform(level.el, translate, scale);
11158		} else {
11159			setPosition(level.el, translate);
11160		}
11161	},
11162
11163	_resetGrid: function () {
11164		var map = this._map,
11165		    crs = map.options.crs,
11166		    tileSize = this._tileSize = this.getTileSize(),
11167		    tileZoom = this._tileZoom;
11168
11169		var bounds = this._map.getPixelWorldBounds(this._tileZoom);
11170		if (bounds) {
11171			this._globalTileRange = this._pxBoundsToTileRange(bounds);
11172		}
11173
11174		this._wrapX = crs.wrapLng && !this.options.noWrap && [
11175			Math.floor(map.project([0, crs.wrapLng[0]], tileZoom).x / tileSize.x),
11176			Math.ceil(map.project([0, crs.wrapLng[1]], tileZoom).x / tileSize.y)
11177		];
11178		this._wrapY = crs.wrapLat && !this.options.noWrap && [
11179			Math.floor(map.project([crs.wrapLat[0], 0], tileZoom).y / tileSize.x),
11180			Math.ceil(map.project([crs.wrapLat[1], 0], tileZoom).y / tileSize.y)
11181		];
11182	},
11183
11184	_onMoveEnd: function () {
11185		if (!this._map || this._map._animatingZoom) { return; }
11186
11187		this._update();
11188	},
11189
11190	_getTiledPixelBounds: function (center) {
11191		var map = this._map,
11192		    mapZoom = map._animatingZoom ? Math.max(map._animateToZoom, map.getZoom()) : map.getZoom(),
11193		    scale = map.getZoomScale(mapZoom, this._tileZoom),
11194		    pixelCenter = map.project(center, this._tileZoom).floor(),
11195		    halfSize = map.getSize().divideBy(scale * 2);
11196
11197		return new Bounds(pixelCenter.subtract(halfSize), pixelCenter.add(halfSize));
11198	},
11199
11200	// Private method to load tiles in the grid's active zoom level according to map bounds
11201	_update: function (center) {
11202		var map = this._map;
11203		if (!map) { return; }
11204		var zoom = this._clampZoom(map.getZoom());
11205
11206		if (center === undefined) { center = map.getCenter(); }
11207		if (this._tileZoom === undefined) { return; }	// if out of minzoom/maxzoom
11208
11209		var pixelBounds = this._getTiledPixelBounds(center),
11210		    tileRange = this._pxBoundsToTileRange(pixelBounds),
11211		    tileCenter = tileRange.getCenter(),
11212		    queue = [],
11213		    margin = this.options.keepBuffer,
11214		    noPruneRange = new Bounds(tileRange.getBottomLeft().subtract([margin, -margin]),
11215		                              tileRange.getTopRight().add([margin, -margin]));
11216
11217		// Sanity check: panic if the tile range contains Infinity somewhere.
11218		if (!(isFinite(tileRange.min.x) &&
11219		      isFinite(tileRange.min.y) &&
11220		      isFinite(tileRange.max.x) &&
11221		      isFinite(tileRange.max.y))) { throw new Error('Attempted to load an infinite number of tiles'); }
11222
11223		for (var key in this._tiles) {
11224			var c = this._tiles[key].coords;
11225			if (c.z !== this._tileZoom || !noPruneRange.contains(new Point(c.x, c.y))) {
11226				this._tiles[key].current = false;
11227			}
11228		}
11229
11230		// _update just loads more tiles. If the tile zoom level differs too much
11231		// from the map's, let _setView reset levels and prune old tiles.
11232		if (Math.abs(zoom - this._tileZoom) > 1) { this._setView(center, zoom); return; }
11233
11234		// create a queue of coordinates to load tiles from
11235		for (var j = tileRange.min.y; j <= tileRange.max.y; j++) {
11236			for (var i = tileRange.min.x; i <= tileRange.max.x; i++) {
11237				var coords = new Point(i, j);
11238				coords.z = this._tileZoom;
11239
11240				if (!this._isValidTile(coords)) { continue; }
11241
11242				var tile = this._tiles[this._tileCoordsToKey(coords)];
11243				if (tile) {
11244					tile.current = true;
11245				} else {
11246					queue.push(coords);
11247				}
11248			}
11249		}
11250
11251		// sort tile queue to load tiles in order of their distance to center
11252		queue.sort(function (a, b) {
11253			return a.distanceTo(tileCenter) - b.distanceTo(tileCenter);
11254		});
11255
11256		if (queue.length !== 0) {
11257			// if it's the first batch of tiles to load
11258			if (!this._loading) {
11259				this._loading = true;
11260				// @event loading: Event
11261				// Fired when the grid layer starts loading tiles.
11262				this.fire('loading');
11263			}
11264
11265			// create DOM fragment to append tiles in one batch
11266			var fragment = document.createDocumentFragment();
11267
11268			for (i = 0; i < queue.length; i++) {
11269				this._addTile(queue[i], fragment);
11270			}
11271
11272			this._level.el.appendChild(fragment);
11273		}
11274	},
11275
11276	_isValidTile: function (coords) {
11277		var crs = this._map.options.crs;
11278
11279		if (!crs.infinite) {
11280			// don't load tile if it's out of bounds and not wrapped
11281			var bounds = this._globalTileRange;
11282			if ((!crs.wrapLng && (coords.x < bounds.min.x || coords.x > bounds.max.x)) ||
11283			    (!crs.wrapLat && (coords.y < bounds.min.y || coords.y > bounds.max.y))) { return false; }
11284		}
11285
11286		if (!this.options.bounds) { return true; }
11287
11288		// don't load tile if it doesn't intersect the bounds in options
11289		var tileBounds = this._tileCoordsToBounds(coords);
11290		return toLatLngBounds(this.options.bounds).overlaps(tileBounds);
11291	},
11292
11293	_keyToBounds: function (key) {
11294		return this._tileCoordsToBounds(this._keyToTileCoords(key));
11295	},
11296
11297	_tileCoordsToNwSe: function (coords) {
11298		var map = this._map,
11299		    tileSize = this.getTileSize(),
11300		    nwPoint = coords.scaleBy(tileSize),
11301		    sePoint = nwPoint.add(tileSize),
11302		    nw = map.unproject(nwPoint, coords.z),
11303		    se = map.unproject(sePoint, coords.z);
11304		return [nw, se];
11305	},
11306
11307	// converts tile coordinates to its geographical bounds
11308	_tileCoordsToBounds: function (coords) {
11309		var bp = this._tileCoordsToNwSe(coords),
11310		    bounds = new LatLngBounds(bp[0], bp[1]);
11311
11312		if (!this.options.noWrap) {
11313			bounds = this._map.wrapLatLngBounds(bounds);
11314		}
11315		return bounds;
11316	},
11317	// converts tile coordinates to key for the tile cache
11318	_tileCoordsToKey: function (coords) {
11319		return coords.x + ':' + coords.y + ':' + coords.z;
11320	},
11321
11322	// converts tile cache key to coordinates
11323	_keyToTileCoords: function (key) {
11324		var k = key.split(':'),
11325		    coords = new Point(+k[0], +k[1]);
11326		coords.z = +k[2];
11327		return coords;
11328	},
11329
11330	_removeTile: function (key) {
11331		var tile = this._tiles[key];
11332		if (!tile) { return; }
11333
11334		remove(tile.el);
11335
11336		delete this._tiles[key];
11337
11338		// @event tileunload: TileEvent
11339		// Fired when a tile is removed (e.g. when a tile goes off the screen).
11340		this.fire('tileunload', {
11341			tile: tile.el,
11342			coords: this._keyToTileCoords(key)
11343		});
11344	},
11345
11346	_initTile: function (tile) {
11347		addClass(tile, 'leaflet-tile');
11348
11349		var tileSize = this.getTileSize();
11350		tile.style.width = tileSize.x + 'px';
11351		tile.style.height = tileSize.y + 'px';
11352
11353		tile.onselectstart = falseFn;
11354		tile.onmousemove = falseFn;
11355
11356		// update opacity on tiles in IE7-8 because of filter inheritance problems
11357		if (ielt9 && this.options.opacity < 1) {
11358			setOpacity(tile, this.options.opacity);
11359		}
11360
11361		// without this hack, tiles disappear after zoom on Chrome for Android
11362		// https://github.com/Leaflet/Leaflet/issues/2078
11363		if (android && !android23) {
11364			tile.style.WebkitBackfaceVisibility = 'hidden';
11365		}
11366	},
11367
11368	_addTile: function (coords, container) {
11369		var tilePos = this._getTilePos(coords),
11370		    key = this._tileCoordsToKey(coords);
11371
11372		var tile = this.createTile(this._wrapCoords(coords), bind(this._tileReady, this, coords));
11373
11374		this._initTile(tile);
11375
11376		// if createTile is defined with a second argument ("done" callback),
11377		// we know that tile is async and will be ready later; otherwise
11378		if (this.createTile.length < 2) {
11379			// mark tile as ready, but delay one frame for opacity animation to happen
11380			requestAnimFrame(bind(this._tileReady, this, coords, null, tile));
11381		}
11382
11383		setPosition(tile, tilePos);
11384
11385		// save tile in cache
11386		this._tiles[key] = {
11387			el: tile,
11388			coords: coords,
11389			current: true
11390		};
11391
11392		container.appendChild(tile);
11393		// @event tileloadstart: TileEvent
11394		// Fired when a tile is requested and starts loading.
11395		this.fire('tileloadstart', {
11396			tile: tile,
11397			coords: coords
11398		});
11399	},
11400
11401	_tileReady: function (coords, err, tile) {
11402		if (err) {
11403			// @event tileerror: TileErrorEvent
11404			// Fired when there is an error loading a tile.
11405			this.fire('tileerror', {
11406				error: err,
11407				tile: tile,
11408				coords: coords
11409			});
11410		}
11411
11412		var key = this._tileCoordsToKey(coords);
11413
11414		tile = this._tiles[key];
11415		if (!tile) { return; }
11416
11417		tile.loaded = +new Date();
11418		if (this._map._fadeAnimated) {
11419			setOpacity(tile.el, 0);
11420			cancelAnimFrame(this._fadeFrame);
11421			this._fadeFrame = requestAnimFrame(this._updateOpacity, this);
11422		} else {
11423			tile.active = true;
11424			this._pruneTiles();
11425		}
11426
11427		if (!err) {
11428			addClass(tile.el, 'leaflet-tile-loaded');
11429
11430			// @event tileload: TileEvent
11431			// Fired when a tile loads.
11432			this.fire('tileload', {
11433				tile: tile.el,
11434				coords: coords
11435			});
11436		}
11437
11438		if (this._noTilesToLoad()) {
11439			this._loading = false;
11440			// @event load: Event
11441			// Fired when the grid layer loaded all visible tiles.
11442			this.fire('load');
11443
11444			if (ielt9 || !this._map._fadeAnimated) {
11445				requestAnimFrame(this._pruneTiles, this);
11446			} else {
11447				// Wait a bit more than 0.2 secs (the duration of the tile fade-in)
11448				// to trigger a pruning.
11449				setTimeout(bind(this._pruneTiles, this), 250);
11450			}
11451		}
11452	},
11453
11454	_getTilePos: function (coords) {
11455		return coords.scaleBy(this.getTileSize()).subtract(this._level.origin);
11456	},
11457
11458	_wrapCoords: function (coords) {
11459		var newCoords = new Point(
11460			this._wrapX ? wrapNum(coords.x, this._wrapX) : coords.x,
11461			this._wrapY ? wrapNum(coords.y, this._wrapY) : coords.y);
11462		newCoords.z = coords.z;
11463		return newCoords;
11464	},
11465
11466	_pxBoundsToTileRange: function (bounds) {
11467		var tileSize = this.getTileSize();
11468		return new Bounds(
11469			bounds.min.unscaleBy(tileSize).floor(),
11470			bounds.max.unscaleBy(tileSize).ceil().subtract([1, 1]));
11471	},
11472
11473	_noTilesToLoad: function () {
11474		for (var key in this._tiles) {
11475			if (!this._tiles[key].loaded) { return false; }
11476		}
11477		return true;
11478	}
11479});
11480
11481// @factory L.gridLayer(options?: GridLayer options)
11482// Creates a new instance of GridLayer with the supplied options.
11483function gridLayer(options) {
11484	return new GridLayer(options);
11485}
11486
11487/*
11488 * @class TileLayer
11489 * @inherits GridLayer
11490 * @aka L.TileLayer
11491 * Used to load and display tile layers on the map. Extends `GridLayer`.
11492 *
11493 * @example
11494 *
11495 * ```js
11496 * L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png?{foo}', {foo: 'bar'}).addTo(map);
11497 * ```
11498 *
11499 * @section URL template
11500 * @example
11501 *
11502 * A string of the following form:
11503 *
11504 * ```
11505 * 'http://{s}.somedomain.com/blabla/{z}/{x}/{y}{r}.png'
11506 * ```
11507 *
11508 * `{s}` means one of the available subdomains (used sequentially to help with browser parallel requests per domain limitation; subdomain values are specified in options; `a`, `b` or `c` by default, can be omitted), `{z}` — zoom level, `{x}` and `{y}` — tile coordinates. `{r}` can be used to add "&commat;2x" to the URL to load retina tiles.
11509 *
11510 * You can use custom keys in the template, which will be [evaluated](#util-template) from TileLayer options, like this:
11511 *
11512 * ```
11513 * L.tileLayer('http://{s}.somedomain.com/{foo}/{z}/{x}/{y}.png', {foo: 'bar'});
11514 * ```
11515 */
11516
11517
11518var TileLayer = GridLayer.extend({
11519
11520	// @section
11521	// @aka TileLayer options
11522	options: {
11523		// @option minZoom: Number = 0
11524		// The minimum zoom level down to which this layer will be displayed (inclusive).
11525		minZoom: 0,
11526
11527		// @option maxZoom: Number = 18
11528		// The maximum zoom level up to which this layer will be displayed (inclusive).
11529		maxZoom: 18,
11530
11531		// @option subdomains: String|String[] = 'abc'
11532		// Subdomains of the tile service. Can be passed in the form of one string (where each letter is a subdomain name) or an array of strings.
11533		subdomains: 'abc',
11534
11535		// @option errorTileUrl: String = ''
11536		// URL to the tile image to show in place of the tile that failed to load.
11537		errorTileUrl: '',
11538
11539		// @option zoomOffset: Number = 0
11540		// The zoom number used in tile URLs will be offset with this value.
11541		zoomOffset: 0,
11542
11543		// @option tms: Boolean = false
11544		// If `true`, inverses Y axis numbering for tiles (turn this on for [TMS](https://en.wikipedia.org/wiki/Tile_Map_Service) services).
11545		tms: false,
11546
11547		// @option zoomReverse: Boolean = false
11548		// If set to true, the zoom number used in tile URLs will be reversed (`maxZoom - zoom` instead of `zoom`)
11549		zoomReverse: false,
11550
11551		// @option detectRetina: Boolean = false
11552		// If `true` and user is on a retina display, it will request four tiles of half the specified size and a bigger zoom level in place of one to utilize the high resolution.
11553		detectRetina: false,
11554
11555		// @option crossOrigin: Boolean|String = false
11556		// Whether the crossOrigin attribute will be added to the tiles.
11557		// If a String is provided, all tiles will have their crossOrigin attribute set to the String provided. This is needed if you want to access tile pixel data.
11558		// Refer to [CORS Settings](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes) for valid String values.
11559		crossOrigin: false
11560	},
11561
11562	initialize: function (url, options) {
11563
11564		this._url = url;
11565
11566		options = setOptions(this, options);
11567
11568		// detecting retina displays, adjusting tileSize and zoom levels
11569		if (options.detectRetina && retina && options.maxZoom > 0) {
11570
11571			options.tileSize = Math.floor(options.tileSize / 2);
11572
11573			if (!options.zoomReverse) {
11574				options.zoomOffset++;
11575				options.maxZoom--;
11576			} else {
11577				options.zoomOffset--;
11578				options.minZoom++;
11579			}
11580
11581			options.minZoom = Math.max(0, options.minZoom);
11582		}
11583
11584		if (typeof options.subdomains === 'string') {
11585			options.subdomains = options.subdomains.split('');
11586		}
11587
11588		// for https://github.com/Leaflet/Leaflet/issues/137
11589		if (!android) {
11590			this.on('tileunload', this._onTileRemove);
11591		}
11592	},
11593
11594	// @method setUrl(url: String, noRedraw?: Boolean): this
11595	// Updates the layer's URL template and redraws it (unless `noRedraw` is set to `true`).
11596	setUrl: function (url, noRedraw) {
11597		this._url = url;
11598
11599		if (!noRedraw) {
11600			this.redraw();
11601		}
11602		return this;
11603	},
11604
11605	// @method createTile(coords: Object, done?: Function): HTMLElement
11606	// Called only internally, overrides GridLayer's [`createTile()`](#gridlayer-createtile)
11607	// to return an `<img>` HTML element with the appropriate image URL given `coords`. The `done`
11608	// callback is called when the tile has been loaded.
11609	createTile: function (coords, done) {
11610		var tile = document.createElement('img');
11611
11612		on(tile, 'load', bind(this._tileOnLoad, this, done, tile));
11613		on(tile, 'error', bind(this._tileOnError, this, done, tile));
11614
11615		if (this.options.crossOrigin || this.options.crossOrigin === '') {
11616			tile.crossOrigin = this.options.crossOrigin === true ? '' : this.options.crossOrigin;
11617		}
11618
11619		/*
11620		 Alt tag is set to empty string to keep screen readers from reading URL and for compliance reasons
11621		 http://www.w3.org/TR/WCAG20-TECHS/H67
11622		*/
11623		tile.alt = '';
11624
11625		/*
11626		 Set role="presentation" to force screen readers to ignore this
11627		 https://www.w3.org/TR/wai-aria/roles#textalternativecomputation
11628		*/
11629		tile.setAttribute('role', 'presentation');
11630
11631		tile.src = this.getTileUrl(coords);
11632
11633		return tile;
11634	},
11635
11636	// @section Extension methods
11637	// @uninheritable
11638	// Layers extending `TileLayer` might reimplement the following method.
11639	// @method getTileUrl(coords: Object): String
11640	// Called only internally, returns the URL for a tile given its coordinates.
11641	// Classes extending `TileLayer` can override this function to provide custom tile URL naming schemes.
11642	getTileUrl: function (coords) {
11643		var data = {
11644			r: retina ? '@2x' : '',
11645			s: this._getSubdomain(coords),
11646			x: coords.x,
11647			y: coords.y,
11648			z: this._getZoomForUrl()
11649		};
11650		if (this._map && !this._map.options.crs.infinite) {
11651			var invertedY = this._globalTileRange.max.y - coords.y;
11652			if (this.options.tms) {
11653				data['y'] = invertedY;
11654			}
11655			data['-y'] = invertedY;
11656		}
11657
11658		return template(this._url, extend(data, this.options));
11659	},
11660
11661	_tileOnLoad: function (done, tile) {
11662		// For https://github.com/Leaflet/Leaflet/issues/3332
11663		if (ielt9) {
11664			setTimeout(bind(done, this, null, tile), 0);
11665		} else {
11666			done(null, tile);
11667		}
11668	},
11669
11670	_tileOnError: function (done, tile, e) {
11671		var errorUrl = this.options.errorTileUrl;
11672		if (errorUrl && tile.getAttribute('src') !== errorUrl) {
11673			tile.src = errorUrl;
11674		}
11675		done(e, tile);
11676	},
11677
11678	_onTileRemove: function (e) {
11679		e.tile.onload = null;
11680	},
11681
11682	_getZoomForUrl: function () {
11683		var zoom = this._tileZoom,
11684		maxZoom = this.options.maxZoom,
11685		zoomReverse = this.options.zoomReverse,
11686		zoomOffset = this.options.zoomOffset;
11687
11688		if (zoomReverse) {
11689			zoom = maxZoom - zoom;
11690		}
11691
11692		return zoom + zoomOffset;
11693	},
11694
11695	_getSubdomain: function (tilePoint) {
11696		var index = Math.abs(tilePoint.x + tilePoint.y) % this.options.subdomains.length;
11697		return this.options.subdomains[index];
11698	},
11699
11700	// stops loading all tiles in the background layer
11701	_abortLoading: function () {
11702		var i, tile;
11703		for (i in this._tiles) {
11704			if (this._tiles[i].coords.z !== this._tileZoom) {
11705				tile = this._tiles[i].el;
11706
11707				tile.onload = falseFn;
11708				tile.onerror = falseFn;
11709
11710				if (!tile.complete) {
11711					tile.src = emptyImageUrl;
11712					remove(tile);
11713					delete this._tiles[i];
11714				}
11715			}
11716		}
11717	},
11718
11719	_removeTile: function (key) {
11720		var tile = this._tiles[key];
11721		if (!tile) { return; }
11722
11723		// Cancels any pending http requests associated with the tile
11724		// unless we're on Android's stock browser,
11725		// see https://github.com/Leaflet/Leaflet/issues/137
11726		if (!androidStock) {
11727			tile.el.setAttribute('src', emptyImageUrl);
11728		}
11729
11730		return GridLayer.prototype._removeTile.call(this, key);
11731	},
11732
11733	_tileReady: function (coords, err, tile) {
11734		if (!this._map || (tile && tile.getAttribute('src') === emptyImageUrl)) {
11735			return;
11736		}
11737
11738		return GridLayer.prototype._tileReady.call(this, coords, err, tile);
11739	}
11740});
11741
11742
11743// @factory L.tilelayer(urlTemplate: String, options?: TileLayer options)
11744// Instantiates a tile layer object given a `URL template` and optionally an options object.
11745
11746function tileLayer(url, options) {
11747	return new TileLayer(url, options);
11748}
11749
11750/*
11751 * @class TileLayer.WMS
11752 * @inherits TileLayer
11753 * @aka L.TileLayer.WMS
11754 * Used to display [WMS](https://en.wikipedia.org/wiki/Web_Map_Service) services as tile layers on the map. Extends `TileLayer`.
11755 *
11756 * @example
11757 *
11758 * ```js
11759 * var nexrad = L.tileLayer.wms("http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r.cgi", {
11760 * 	layers: 'nexrad-n0r-900913',
11761 * 	format: 'image/png',
11762 * 	transparent: true,
11763 * 	attribution: "Weather data © 2012 IEM Nexrad"
11764 * });
11765 * ```
11766 */
11767
11768var TileLayerWMS = TileLayer.extend({
11769
11770	// @section
11771	// @aka TileLayer.WMS options
11772	// If any custom options not documented here are used, they will be sent to the
11773	// WMS server as extra parameters in each request URL. This can be useful for
11774	// [non-standard vendor WMS parameters](http://docs.geoserver.org/stable/en/user/services/wms/vendor.html).
11775	defaultWmsParams: {
11776		service: 'WMS',
11777		request: 'GetMap',
11778
11779		// @option layers: String = ''
11780		// **(required)** Comma-separated list of WMS layers to show.
11781		layers: '',
11782
11783		// @option styles: String = ''
11784		// Comma-separated list of WMS styles.
11785		styles: '',
11786
11787		// @option format: String = 'image/jpeg'
11788		// WMS image format (use `'image/png'` for layers with transparency).
11789		format: 'image/jpeg',
11790
11791		// @option transparent: Boolean = false
11792		// If `true`, the WMS service will return images with transparency.
11793		transparent: false,
11794
11795		// @option version: String = '1.1.1'
11796		// Version of the WMS service to use
11797		version: '1.1.1'
11798	},
11799
11800	options: {
11801		// @option crs: CRS = null
11802		// Coordinate Reference System to use for the WMS requests, defaults to
11803		// map CRS. Don't change this if you're not sure what it means.
11804		crs: null,
11805
11806		// @option uppercase: Boolean = false
11807		// If `true`, WMS request parameter keys will be uppercase.
11808		uppercase: false
11809	},
11810
11811	initialize: function (url, options) {
11812
11813		this._url = url;
11814
11815		var wmsParams = extend({}, this.defaultWmsParams);
11816
11817		// all keys that are not TileLayer options go to WMS params
11818		for (var i in options) {
11819			if (!(i in this.options)) {
11820				wmsParams[i] = options[i];
11821			}
11822		}
11823
11824		options = setOptions(this, options);
11825
11826		var realRetina = options.detectRetina && retina ? 2 : 1;
11827		var tileSize = this.getTileSize();
11828		wmsParams.width = tileSize.x * realRetina;
11829		wmsParams.height = tileSize.y * realRetina;
11830
11831		this.wmsParams = wmsParams;
11832	},
11833
11834	onAdd: function (map) {
11835
11836		this._crs = this.options.crs || map.options.crs;
11837		this._wmsVersion = parseFloat(this.wmsParams.version);
11838
11839		var projectionKey = this._wmsVersion >= 1.3 ? 'crs' : 'srs';
11840		this.wmsParams[projectionKey] = this._crs.code;
11841
11842		TileLayer.prototype.onAdd.call(this, map);
11843	},
11844
11845	getTileUrl: function (coords) {
11846
11847		var tileBounds = this._tileCoordsToNwSe(coords),
11848		    crs = this._crs,
11849		    bounds = toBounds(crs.project(tileBounds[0]), crs.project(tileBounds[1])),
11850		    min = bounds.min,
11851		    max = bounds.max,
11852		    bbox = (this._wmsVersion >= 1.3 && this._crs === EPSG4326 ?
11853		    [min.y, min.x, max.y, max.x] :
11854		    [min.x, min.y, max.x, max.y]).join(','),
11855		    url = TileLayer.prototype.getTileUrl.call(this, coords);
11856		return url +
11857			getParamString(this.wmsParams, url, this.options.uppercase) +
11858			(this.options.uppercase ? '&BBOX=' : '&bbox=') + bbox;
11859	},
11860
11861	// @method setParams(params: Object, noRedraw?: Boolean): this
11862	// Merges an object with the new parameters and re-requests tiles on the current screen (unless `noRedraw` was set to true).
11863	setParams: function (params, noRedraw) {
11864
11865		extend(this.wmsParams, params);
11866
11867		if (!noRedraw) {
11868			this.redraw();
11869		}
11870
11871		return this;
11872	}
11873});
11874
11875
11876// @factory L.tileLayer.wms(baseUrl: String, options: TileLayer.WMS options)
11877// Instantiates a WMS tile layer object given a base URL of the WMS service and a WMS parameters/options object.
11878function tileLayerWMS(url, options) {
11879	return new TileLayerWMS(url, options);
11880}
11881
11882TileLayer.WMS = TileLayerWMS;
11883tileLayer.wms = tileLayerWMS;
11884
11885/*
11886 * @class Renderer
11887 * @inherits Layer
11888 * @aka L.Renderer
11889 *
11890 * Base class for vector renderer implementations (`SVG`, `Canvas`). Handles the
11891 * DOM container of the renderer, its bounds, and its zoom animation.
11892 *
11893 * A `Renderer` works as an implicit layer group for all `Path`s - the renderer
11894 * itself can be added or removed to the map. All paths use a renderer, which can
11895 * be implicit (the map will decide the type of renderer and use it automatically)
11896 * or explicit (using the [`renderer`](#path-renderer) option of the path).
11897 *
11898 * Do not use this class directly, use `SVG` and `Canvas` instead.
11899 *
11900 * @event update: Event
11901 * Fired when the renderer updates its bounds, center and zoom, for example when
11902 * its map has moved
11903 */
11904
11905var Renderer = Layer.extend({
11906
11907	// @section
11908	// @aka Renderer options
11909	options: {
11910		// @option padding: Number = 0.1
11911		// How much to extend the clip area around the map view (relative to its size)
11912		// e.g. 0.1 would be 10% of map view in each direction
11913		padding: 0.1,
11914
11915		// @option tolerance: Number = 0
11916		// How much to extend click tolerance round a path/object on the map
11917		tolerance : 0
11918	},
11919
11920	initialize: function (options) {
11921		setOptions(this, options);
11922		stamp(this);
11923		this._layers = this._layers || {};
11924	},
11925
11926	onAdd: function () {
11927		if (!this._container) {
11928			this._initContainer(); // defined by renderer implementations
11929
11930			if (this._zoomAnimated) {
11931				addClass(this._container, 'leaflet-zoom-animated');
11932			}
11933		}
11934
11935		this.getPane().appendChild(this._container);
11936		this._update();
11937		this.on('update', this._updatePaths, this);
11938	},
11939
11940	onRemove: function () {
11941		this.off('update', this._updatePaths, this);
11942		this._destroyContainer();
11943	},
11944
11945	getEvents: function () {
11946		var events = {
11947			viewreset: this._reset,
11948			zoom: this._onZoom,
11949			moveend: this._update,
11950			zoomend: this._onZoomEnd
11951		};
11952		if (this._zoomAnimated) {
11953			events.zoomanim = this._onAnimZoom;
11954		}
11955		return events;
11956	},
11957
11958	_onAnimZoom: function (ev) {
11959		this._updateTransform(ev.center, ev.zoom);
11960	},
11961
11962	_onZoom: function () {
11963		this._updateTransform(this._map.getCenter(), this._map.getZoom());
11964	},
11965
11966	_updateTransform: function (center, zoom) {
11967		var scale = this._map.getZoomScale(zoom, this._zoom),
11968		    position = getPosition(this._container),
11969		    viewHalf = this._map.getSize().multiplyBy(0.5 + this.options.padding),
11970		    currentCenterPoint = this._map.project(this._center, zoom),
11971		    destCenterPoint = this._map.project(center, zoom),
11972		    centerOffset = destCenterPoint.subtract(currentCenterPoint),
11973
11974		    topLeftOffset = viewHalf.multiplyBy(-scale).add(position).add(viewHalf).subtract(centerOffset);
11975
11976		if (any3d) {
11977			setTransform(this._container, topLeftOffset, scale);
11978		} else {
11979			setPosition(this._container, topLeftOffset);
11980		}
11981	},
11982
11983	_reset: function () {
11984		this._update();
11985		this._updateTransform(this._center, this._zoom);
11986
11987		for (var id in this._layers) {
11988			this._layers[id]._reset();
11989		}
11990	},
11991
11992	_onZoomEnd: function () {
11993		for (var id in this._layers) {
11994			this._layers[id]._project();
11995		}
11996	},
11997
11998	_updatePaths: function () {
11999		for (var id in this._layers) {
12000			this._layers[id]._update();
12001		}
12002	},
12003
12004	_update: function () {
12005		// Update pixel bounds of renderer container (for positioning/sizing/clipping later)
12006		// Subclasses are responsible of firing the 'update' event.
12007		var p = this.options.padding,
12008		    size = this._map.getSize(),
12009		    min = this._map.containerPointToLayerPoint(size.multiplyBy(-p)).round();
12010
12011		this._bounds = new Bounds(min, min.add(size.multiplyBy(1 + p * 2)).round());
12012
12013		this._center = this._map.getCenter();
12014		this._zoom = this._map.getZoom();
12015	}
12016});
12017
12018/*
12019 * @class Canvas
12020 * @inherits Renderer
12021 * @aka L.Canvas
12022 *
12023 * Allows vector layers to be displayed with [`<canvas>`](https://developer.mozilla.org/docs/Web/API/Canvas_API).
12024 * Inherits `Renderer`.
12025 *
12026 * Due to [technical limitations](http://caniuse.com/#search=canvas), Canvas is not
12027 * available in all web browsers, notably IE8, and overlapping geometries might
12028 * not display properly in some edge cases.
12029 *
12030 * @example
12031 *
12032 * Use Canvas by default for all paths in the map:
12033 *
12034 * ```js
12035 * var map = L.map('map', {
12036 * 	renderer: L.canvas()
12037 * });
12038 * ```
12039 *
12040 * Use a Canvas renderer with extra padding for specific vector geometries:
12041 *
12042 * ```js
12043 * var map = L.map('map');
12044 * var myRenderer = L.canvas({ padding: 0.5 });
12045 * var line = L.polyline( coordinates, { renderer: myRenderer } );
12046 * var circle = L.circle( center, { renderer: myRenderer } );
12047 * ```
12048 */
12049
12050var Canvas = Renderer.extend({
12051	getEvents: function () {
12052		var events = Renderer.prototype.getEvents.call(this);
12053		events.viewprereset = this._onViewPreReset;
12054		return events;
12055	},
12056
12057	_onViewPreReset: function () {
12058		// Set a flag so that a viewprereset+moveend+viewreset only updates&redraws once
12059		this._postponeUpdatePaths = true;
12060	},
12061
12062	onAdd: function () {
12063		Renderer.prototype.onAdd.call(this);
12064
12065		// Redraw vectors since canvas is cleared upon removal,
12066		// in case of removing the renderer itself from the map.
12067		this._draw();
12068	},
12069
12070	_initContainer: function () {
12071		var container = this._container = document.createElement('canvas');
12072
12073		on(container, 'mousemove', throttle(this._onMouseMove, 32, this), this);
12074		on(container, 'click dblclick mousedown mouseup contextmenu', this._onClick, this);
12075		on(container, 'mouseout', this._handleMouseOut, this);
12076
12077		this._ctx = container.getContext('2d');
12078	},
12079
12080	_destroyContainer: function () {
12081		cancelAnimFrame(this._redrawRequest);
12082		delete this._ctx;
12083		remove(this._container);
12084		off(this._container);
12085		delete this._container;
12086	},
12087
12088	_updatePaths: function () {
12089		if (this._postponeUpdatePaths) { return; }
12090
12091		var layer;
12092		this._redrawBounds = null;
12093		for (var id in this._layers) {
12094			layer = this._layers[id];
12095			layer._update();
12096		}
12097		this._redraw();
12098	},
12099
12100	_update: function () {
12101		if (this._map._animatingZoom && this._bounds) { return; }
12102
12103		this._drawnLayers = {};
12104
12105		Renderer.prototype._update.call(this);
12106
12107		var b = this._bounds,
12108		    container = this._container,
12109		    size = b.getSize(),
12110		    m = retina ? 2 : 1;
12111
12112		setPosition(container, b.min);
12113
12114		// set canvas size (also clearing it); use double size on retina
12115		container.width = m * size.x;
12116		container.height = m * size.y;
12117		container.style.width = size.x + 'px';
12118		container.style.height = size.y + 'px';
12119
12120		if (retina) {
12121			this._ctx.scale(2, 2);
12122		}
12123
12124		// translate so we use the same path coordinates after canvas element moves
12125		this._ctx.translate(-b.min.x, -b.min.y);
12126
12127		// Tell paths to redraw themselves
12128		this.fire('update');
12129	},
12130
12131	_reset: function () {
12132		Renderer.prototype._reset.call(this);
12133
12134		if (this._postponeUpdatePaths) {
12135			this._postponeUpdatePaths = false;
12136			this._updatePaths();
12137		}
12138	},
12139
12140	_initPath: function (layer) {
12141		this._updateDashArray(layer);
12142		this._layers[stamp(layer)] = layer;
12143
12144		var order = layer._order = {
12145			layer: layer,
12146			prev: this._drawLast,
12147			next: null
12148		};
12149		if (this._drawLast) { this._drawLast.next = order; }
12150		this._drawLast = order;
12151		this._drawFirst = this._drawFirst || this._drawLast;
12152	},
12153
12154	_addPath: function (layer) {
12155		this._requestRedraw(layer);
12156	},
12157
12158	_removePath: function (layer) {
12159		var order = layer._order;
12160		var next = order.next;
12161		var prev = order.prev;
12162
12163		if (next) {
12164			next.prev = prev;
12165		} else {
12166			this._drawLast = prev;
12167		}
12168		if (prev) {
12169			prev.next = next;
12170		} else {
12171			this._drawFirst = next;
12172		}
12173
12174		delete this._drawnLayers[layer._leaflet_id];
12175
12176		delete layer._order;
12177
12178		delete this._layers[stamp(layer)];
12179
12180		this._requestRedraw(layer);
12181	},
12182
12183	_updatePath: function (layer) {
12184		// Redraw the union of the layer's old pixel
12185		// bounds and the new pixel bounds.
12186		this._extendRedrawBounds(layer);
12187		layer._project();
12188		layer._update();
12189		// The redraw will extend the redraw bounds
12190		// with the new pixel bounds.
12191		this._requestRedraw(layer);
12192	},
12193
12194	_updateStyle: function (layer) {
12195		this._updateDashArray(layer);
12196		this._requestRedraw(layer);
12197	},
12198
12199	_updateDashArray: function (layer) {
12200		if (typeof layer.options.dashArray === 'string') {
12201			var parts = layer.options.dashArray.split(/[, ]+/),
12202			    dashArray = [],
12203			    i;
12204			for (i = 0; i < parts.length; i++) {
12205				dashArray.push(Number(parts[i]));
12206			}
12207			layer.options._dashArray = dashArray;
12208		} else {
12209			layer.options._dashArray = layer.options.dashArray;
12210		}
12211	},
12212
12213	_requestRedraw: function (layer) {
12214		if (!this._map) { return; }
12215
12216		this._extendRedrawBounds(layer);
12217		this._redrawRequest = this._redrawRequest || requestAnimFrame(this._redraw, this);
12218	},
12219
12220	_extendRedrawBounds: function (layer) {
12221		if (layer._pxBounds) {
12222			var padding = (layer.options.weight || 0) + 1;
12223			this._redrawBounds = this._redrawBounds || new Bounds();
12224			this._redrawBounds.extend(layer._pxBounds.min.subtract([padding, padding]));
12225			this._redrawBounds.extend(layer._pxBounds.max.add([padding, padding]));
12226		}
12227	},
12228
12229	_redraw: function () {
12230		this._redrawRequest = null;
12231
12232		if (this._redrawBounds) {
12233			this._redrawBounds.min._floor();
12234			this._redrawBounds.max._ceil();
12235		}
12236
12237		this._clear(); // clear layers in redraw bounds
12238		this._draw(); // draw layers
12239
12240		this._redrawBounds = null;
12241	},
12242
12243	_clear: function () {
12244		var bounds = this._redrawBounds;
12245		if (bounds) {
12246			var size = bounds.getSize();
12247			this._ctx.clearRect(bounds.min.x, bounds.min.y, size.x, size.y);
12248		} else {
12249			this._ctx.clearRect(0, 0, this._container.width, this._container.height);
12250		}
12251	},
12252
12253	_draw: function () {
12254		var layer, bounds = this._redrawBounds;
12255		this._ctx.save();
12256		if (bounds) {
12257			var size = bounds.getSize();
12258			this._ctx.beginPath();
12259			this._ctx.rect(bounds.min.x, bounds.min.y, size.x, size.y);
12260			this._ctx.clip();
12261		}
12262
12263		this._drawing = true;
12264
12265		for (var order = this._drawFirst; order; order = order.next) {
12266			layer = order.layer;
12267			if (!bounds || (layer._pxBounds && layer._pxBounds.intersects(bounds))) {
12268				layer._updatePath();
12269			}
12270		}
12271
12272		this._drawing = false;
12273
12274		this._ctx.restore();  // Restore state before clipping.
12275	},
12276
12277	_updatePoly: function (layer, closed) {
12278		if (!this._drawing) { return; }
12279
12280		var i, j, len2, p,
12281		    parts = layer._parts,
12282		    len = parts.length,
12283		    ctx = this._ctx;
12284
12285		if (!len) { return; }
12286
12287		this._drawnLayers[layer._leaflet_id] = layer;
12288
12289		ctx.beginPath();
12290
12291		for (i = 0; i < len; i++) {
12292			for (j = 0, len2 = parts[i].length; j < len2; j++) {
12293				p = parts[i][j];
12294				ctx[j ? 'lineTo' : 'moveTo'](p.x, p.y);
12295			}
12296			if (closed) {
12297				ctx.closePath();
12298			}
12299		}
12300
12301		this._fillStroke(ctx, layer);
12302
12303		// TODO optimization: 1 fill/stroke for all features with equal style instead of 1 for each feature
12304	},
12305
12306	_updateCircle: function (layer) {
12307
12308		if (!this._drawing || layer._empty()) { return; }
12309
12310		var p = layer._point,
12311		    ctx = this._ctx,
12312		    r = Math.max(Math.round(layer._radius), 1),
12313		    s = (Math.max(Math.round(layer._radiusY), 1) || r) / r;
12314
12315		this._drawnLayers[layer._leaflet_id] = layer;
12316
12317		if (s !== 1) {
12318			ctx.save();
12319			ctx.scale(1, s);
12320		}
12321
12322		ctx.beginPath();
12323		ctx.arc(p.x, p.y / s, r, 0, Math.PI * 2, false);
12324
12325		if (s !== 1) {
12326			ctx.restore();
12327		}
12328
12329		this._fillStroke(ctx, layer);
12330	},
12331
12332	_fillStroke: function (ctx, layer) {
12333		var options = layer.options;
12334
12335		if (options.fill) {
12336			ctx.globalAlpha = options.fillOpacity;
12337			ctx.fillStyle = options.fillColor || options.color;
12338			ctx.fill(options.fillRule || 'evenodd');
12339		}
12340
12341		if (options.stroke && options.weight !== 0) {
12342			if (ctx.setLineDash) {
12343				ctx.setLineDash(layer.options && layer.options._dashArray || []);
12344			}
12345			ctx.globalAlpha = options.opacity;
12346			ctx.lineWidth = options.weight;
12347			ctx.strokeStyle = options.color;
12348			ctx.lineCap = options.lineCap;
12349			ctx.lineJoin = options.lineJoin;
12350			ctx.stroke();
12351		}
12352	},
12353
12354	// Canvas obviously doesn't have mouse events for individual drawn objects,
12355	// so we emulate that by calculating what's under the mouse on mousemove/click manually
12356
12357	_onClick: function (e) {
12358		var point = this._map.mouseEventToLayerPoint(e), layer, clickedLayer;
12359
12360		for (var order = this._drawFirst; order; order = order.next) {
12361			layer = order.layer;
12362			if (layer.options.interactive && layer._containsPoint(point) && !this._map._draggableMoved(layer)) {
12363				clickedLayer = layer;
12364			}
12365		}
12366		if (clickedLayer)  {
12367			fakeStop(e);
12368			this._fireEvent([clickedLayer], e);
12369		}
12370	},
12371
12372	_onMouseMove: function (e) {
12373		if (!this._map || this._map.dragging.moving() || this._map._animatingZoom) { return; }
12374
12375		var point = this._map.mouseEventToLayerPoint(e);
12376		this._handleMouseHover(e, point);
12377	},
12378
12379
12380	_handleMouseOut: function (e) {
12381		var layer = this._hoveredLayer;
12382		if (layer) {
12383			// if we're leaving the layer, fire mouseout
12384			removeClass(this._container, 'leaflet-interactive');
12385			this._fireEvent([layer], e, 'mouseout');
12386			this._hoveredLayer = null;
12387		}
12388	},
12389
12390	_handleMouseHover: function (e, point) {
12391		var layer, candidateHoveredLayer;
12392
12393		for (var order = this._drawFirst; order; order = order.next) {
12394			layer = order.layer;
12395			if (layer.options.interactive && layer._containsPoint(point)) {
12396				candidateHoveredLayer = layer;
12397			}
12398		}
12399
12400		if (candidateHoveredLayer !== this._hoveredLayer) {
12401			this._handleMouseOut(e);
12402
12403			if (candidateHoveredLayer) {
12404				addClass(this._container, 'leaflet-interactive'); // change cursor
12405				this._fireEvent([candidateHoveredLayer], e, 'mouseover');
12406				this._hoveredLayer = candidateHoveredLayer;
12407			}
12408		}
12409
12410		if (this._hoveredLayer) {
12411			this._fireEvent([this._hoveredLayer], e);
12412		}
12413	},
12414
12415	_fireEvent: function (layers, e, type) {
12416		this._map._fireDOMEvent(e, type || e.type, layers);
12417	},
12418
12419	_bringToFront: function (layer) {
12420		var order = layer._order;
12421		var next = order.next;
12422		var prev = order.prev;
12423
12424		if (next) {
12425			next.prev = prev;
12426		} else {
12427			// Already last
12428			return;
12429		}
12430		if (prev) {
12431			prev.next = next;
12432		} else if (next) {
12433			// Update first entry unless this is the
12434			// single entry
12435			this._drawFirst = next;
12436		}
12437
12438		order.prev = this._drawLast;
12439		this._drawLast.next = order;
12440
12441		order.next = null;
12442		this._drawLast = order;
12443
12444		this._requestRedraw(layer);
12445	},
12446
12447	_bringToBack: function (layer) {
12448		var order = layer._order;
12449		var next = order.next;
12450		var prev = order.prev;
12451
12452		if (prev) {
12453			prev.next = next;
12454		} else {
12455			// Already first
12456			return;
12457		}
12458		if (next) {
12459			next.prev = prev;
12460		} else if (prev) {
12461			// Update last entry unless this is the
12462			// single entry
12463			this._drawLast = prev;
12464		}
12465
12466		order.prev = null;
12467
12468		order.next = this._drawFirst;
12469		this._drawFirst.prev = order;
12470		this._drawFirst = order;
12471
12472		this._requestRedraw(layer);
12473	}
12474});
12475
12476// @factory L.canvas(options?: Renderer options)
12477// Creates a Canvas renderer with the given options.
12478function canvas$1(options) {
12479	return canvas ? new Canvas(options) : null;
12480}
12481
12482/*
12483 * Thanks to Dmitry Baranovsky and his Raphael library for inspiration!
12484 */
12485
12486
12487var vmlCreate = (function () {
12488	try {
12489		document.namespaces.add('lvml', 'urn:schemas-microsoft-com:vml');
12490		return function (name) {
12491			return document.createElement('<lvml:' + name + ' class="lvml">');
12492		};
12493	} catch (e) {
12494		return function (name) {
12495			return document.createElement('<' + name + ' xmlns="urn:schemas-microsoft.com:vml" class="lvml">');
12496		};
12497	}
12498})();
12499
12500
12501/*
12502 * @class SVG
12503 *
12504 * Although SVG is not available on IE7 and IE8, these browsers support [VML](https://en.wikipedia.org/wiki/Vector_Markup_Language), and the SVG renderer will fall back to VML in this case.
12505 *
vendor: 27,130 bytes, lines 12506-13536
12506 * VML was deprecated in 2012, which means VML functionality exists only for backwards compatibility
12507 * with old versions of Internet Explorer.
12508 */
12509
12510// mixin to redefine some SVG methods to handle VML syntax which is similar but with some differences
12511var vmlMixin = {
12512
12513	_initContainer: function () {
12514		this._container = create$1('div', 'leaflet-vml-container');
12515	},
12516
12517	_update: function () {
12518		if (this._map._animatingZoom) { return; }
12519		Renderer.prototype._update.call(this);
12520		this.fire('update');
12521	},
12522
12523	_initPath: function (layer) {
12524		var container = layer._container = vmlCreate('shape');
12525
12526		addClass(container, 'leaflet-vml-shape ' + (this.options.className || ''));
12527
12528		container.coordsize = '1 1';
12529
12530		layer._path = vmlCreate('path');
12531		container.appendChild(layer._path);
12532
12533		this._updateStyle(layer);
12534		this._layers[stamp(layer)] = layer;
12535	},
12536
12537	_addPath: function (layer) {
12538		var container = layer._container;
12539		this._container.appendChild(container);
12540
12541		if (layer.options.interactive) {
12542			layer.addInteractiveTarget(container);
12543		}
12544	},
12545
12546	_removePath: function (layer) {
12547		var container = layer._container;
12548		remove(container);
12549		layer.removeInteractiveTarget(container);
12550		delete this._layers[stamp(layer)];
12551	},
12552
12553	_updateStyle: function (layer) {
12554		var stroke = layer._stroke,
12555		    fill = layer._fill,
12556		    options = layer.options,
12557		    container = layer._container;
12558
12559		container.stroked = !!options.stroke;
12560		container.filled = !!options.fill;
12561
12562		if (options.stroke) {
12563			if (!stroke) {
12564				stroke = layer._stroke = vmlCreate('stroke');
12565			}
12566			container.appendChild(stroke);
12567			stroke.weight = options.weight + 'px';
12568			stroke.color = options.color;
12569			stroke.opacity = options.opacity;
12570
12571			if (options.dashArray) {
12572				stroke.dashStyle = isArray(options.dashArray) ?
12573				    options.dashArray.join(' ') :
12574				    options.dashArray.replace(/( *, *)/g, ' ');
12575			} else {
12576				stroke.dashStyle = '';
12577			}
12578			stroke.endcap = options.lineCap.replace('butt', 'flat');
12579			stroke.joinstyle = options.lineJoin;
12580
12581		} else if (stroke) {
12582			container.removeChild(stroke);
12583			layer._stroke = null;
12584		}
12585
12586		if (options.fill) {
12587			if (!fill) {
12588				fill = layer._fill = vmlCreate('fill');
12589			}
12590			container.appendChild(fill);
12591			fill.color = options.fillColor || options.color;
12592			fill.opacity = options.fillOpacity;
12593
12594		} else if (fill) {
12595			container.removeChild(fill);
12596			layer._fill = null;
12597		}
12598	},
12599
12600	_updateCircle: function (layer) {
12601		var p = layer._point.round(),
12602		    r = Math.round(layer._radius),
12603		    r2 = Math.round(layer._radiusY || r);
12604
12605		this._setPath(layer, layer._empty() ? 'M0 0' :
12606			'AL ' + p.x + ',' + p.y + ' ' + r + ',' + r2 + ' 0,' + (65535 * 360));
12607	},
12608
12609	_setPath: function (layer, path) {
12610		layer._path.v = path;
12611	},
12612
12613	_bringToFront: function (layer) {
12614		toFront(layer._container);
12615	},
12616
12617	_bringToBack: function (layer) {
12618		toBack(layer._container);
12619	}
12620};
12621
12622var create$2 = vml ? vmlCreate : svgCreate;
12623
12624/*
12625 * @class SVG
12626 * @inherits Renderer
12627 * @aka L.SVG
12628 *
12629 * Allows vector layers to be displayed with [SVG](https://developer.mozilla.org/docs/Web/SVG).
12630 * Inherits `Renderer`.
12631 *
12632 * Due to [technical limitations](http://caniuse.com/#search=svg), SVG is not
12633 * available in all web browsers, notably Android 2.x and 3.x.
12634 *
12635 * Although SVG is not available on IE7 and IE8, these browsers support
12636 * [VML](https://en.wikipedia.org/wiki/Vector_Markup_Language)
12637 * (a now deprecated technology), and the SVG renderer will fall back to VML in
12638 * this case.
12639 *
12640 * @example
12641 *
12642 * Use SVG by default for all paths in the map:
12643 *
12644 * ```js
12645 * var map = L.map('map', {
12646 * 	renderer: L.svg()
12647 * });
12648 * ```
12649 *
12650 * Use a SVG renderer with extra padding for specific vector geometries:
12651 *
12652 * ```js
12653 * var map = L.map('map');
12654 * var myRenderer = L.svg({ padding: 0.5 });
12655 * var line = L.polyline( coordinates, { renderer: myRenderer } );
12656 * var circle = L.circle( center, { renderer: myRenderer } );
12657 * ```
12658 */
12659
12660var SVG = Renderer.extend({
12661
12662	getEvents: function () {
12663		var events = Renderer.prototype.getEvents.call(this);
12664		events.zoomstart = this._onZoomStart;
12665		return events;
12666	},
12667
12668	_initContainer: function () {
12669		this._container = create$2('svg');
12670
12671		// makes it possible to click through svg root; we'll reset it back in individual paths
12672		this._container.setAttribute('pointer-events', 'none');
12673
12674		this._rootGroup = create$2('g');
12675		this._container.appendChild(this._rootGroup);
12676	},
12677
12678	_destroyContainer: function () {
12679		remove(this._container);
12680		off(this._container);
12681		delete this._container;
12682		delete this._rootGroup;
12683		delete this._svgSize;
12684	},
12685
12686	_onZoomStart: function () {
12687		// Drag-then-pinch interactions might mess up the center and zoom.
12688		// In this case, the easiest way to prevent this is re-do the renderer
12689		//   bounds and padding when the zooming starts.
12690		this._update();
12691	},
12692
12693	_update: function () {
12694		if (this._map._animatingZoom && this._bounds) { return; }
12695
12696		Renderer.prototype._update.call(this);
12697
12698		var b = this._bounds,
12699		    size = b.getSize(),
12700		    container = this._container;
12701
12702		// set size of svg-container if changed
12703		if (!this._svgSize || !this._svgSize.equals(size)) {
12704			this._svgSize = size;
12705			container.setAttribute('width', size.x);
12706			container.setAttribute('height', size.y);
12707		}
12708
12709		// movement: update container viewBox so that we don't have to change coordinates of individual layers
12710		setPosition(container, b.min);
12711		container.setAttribute('viewBox', [b.min.x, b.min.y, size.x, size.y].join(' '));
12712
12713		this.fire('update');
12714	},
12715
12716	// methods below are called by vector layers implementations
12717
12718	_initPath: function (layer) {
12719		var path = layer._path = create$2('path');
12720
12721		// @namespace Path
12722		// @option className: String = null
12723		// Custom class name set on an element. Only for SVG renderer.
12724		if (layer.options.className) {
12725			addClass(path, layer.options.className);
12726		}
12727
12728		if (layer.options.interactive) {
12729			addClass(path, 'leaflet-interactive');
12730		}
12731
12732		this._updateStyle(layer);
12733		this._layers[stamp(layer)] = layer;
12734	},
12735
12736	_addPath: function (layer) {
12737		if (!this._rootGroup) { this._initContainer(); }
12738		this._rootGroup.appendChild(layer._path);
12739		layer.addInteractiveTarget(layer._path);
12740	},
12741
12742	_removePath: function (layer) {
12743		remove(layer._path);
12744		layer.removeInteractiveTarget(layer._path);
12745		delete this._layers[stamp(layer)];
12746	},
12747
12748	_updatePath: function (layer) {
12749		layer._project();
12750		layer._update();
12751	},
12752
12753	_updateStyle: function (layer) {
12754		var path = layer._path,
12755		    options = layer.options;
12756
12757		if (!path) { return; }
12758
12759		if (options.stroke) {
12760			path.setAttribute('stroke', options.color);
12761			path.setAttribute('stroke-opacity', options.opacity);
12762			path.setAttribute('stroke-width', options.weight);
12763			path.setAttribute('stroke-linecap', options.lineCap);
12764			path.setAttribute('stroke-linejoin', options.lineJoin);
12765
12766			if (options.dashArray) {
12767				path.setAttribute('stroke-dasharray', options.dashArray);
12768			} else {
12769				path.removeAttribute('stroke-dasharray');
12770			}
12771
12772			if (options.dashOffset) {
12773				path.setAttribute('stroke-dashoffset', options.dashOffset);
12774			} else {
12775				path.removeAttribute('stroke-dashoffset');
12776			}
12777		} else {
12778			path.setAttribute('stroke', 'none');
12779		}
12780
12781		if (options.fill) {
12782			path.setAttribute('fill', options.fillColor || options.color);
12783			path.setAttribute('fill-opacity', options.fillOpacity);
12784			path.setAttribute('fill-rule', options.fillRule || 'evenodd');
12785		} else {
12786			path.setAttribute('fill', 'none');
12787		}
12788	},
12789
12790	_updatePoly: function (layer, closed) {
12791		this._setPath(layer, pointsToPath(layer._parts, closed));
12792	},
12793
12794	_updateCircle: function (layer) {
12795		var p = layer._point,
12796		    r = Math.max(Math.round(layer._radius), 1),
12797		    r2 = Math.max(Math.round(layer._radiusY), 1) || r,
12798		    arc = 'a' + r + ',' + r2 + ' 0 1,0 ';
12799
12800		// drawing a circle with two half-arcs
12801		var d = layer._empty() ? 'M0 0' :
12802			'M' + (p.x - r) + ',' + p.y +
12803			arc + (r * 2) + ',0 ' +
12804			arc + (-r * 2) + ',0 ';
12805
12806		this._setPath(layer, d);
12807	},
12808
12809	_setPath: function (layer, path) {
12810		layer._path.setAttribute('d', path);
12811	},
12812
12813	// SVG does not have the concept of zIndex so we resort to changing the DOM order of elements
12814	_bringToFront: function (layer) {
12815		toFront(layer._path);
12816	},
12817
12818	_bringToBack: function (layer) {
12819		toBack(layer._path);
12820	}
12821});
12822
12823if (vml) {
12824	SVG.include(vmlMixin);
12825}
12826
12827// @namespace SVG
12828// @factory L.svg(options?: Renderer options)
12829// Creates a SVG renderer with the given options.
12830function svg$1(options) {
12831	return svg || vml ? new SVG(options) : null;
12832}
12833
12834Map.include({
12835	// @namespace Map; @method getRenderer(layer: Path): Renderer
12836	// Returns the instance of `Renderer` that should be used to render the given
12837	// `Path`. It will ensure that the `renderer` options of the map and paths
12838	// are respected, and that the renderers do exist on the map.
12839	getRenderer: function (layer) {
12840		// @namespace Path; @option renderer: Renderer
12841		// Use this specific instance of `Renderer` for this path. Takes
12842		// precedence over the map's [default renderer](#map-renderer).
12843		var renderer = layer.options.renderer || this._getPaneRenderer(layer.options.pane) || this.options.renderer || this._renderer;
12844
12845		if (!renderer) {
12846			renderer = this._renderer = this._createRenderer();
12847		}
12848
12849		if (!this.hasLayer(renderer)) {
12850			this.addLayer(renderer);
12851		}
12852		return renderer;
12853	},
12854
12855	_getPaneRenderer: function (name) {
12856		if (name === 'overlayPane' || name === undefined) {
12857			return false;
12858		}
12859
12860		var renderer = this._paneRenderers[name];
12861		if (renderer === undefined) {
12862			renderer = this._createRenderer({pane: name});
12863			this._paneRenderers[name] = renderer;
12864		}
12865		return renderer;
12866	},
12867
12868	_createRenderer: function (options) {
12869		// @namespace Map; @option preferCanvas: Boolean = false
12870		// Whether `Path`s should be rendered on a `Canvas` renderer.
12871		// By default, all `Path`s are rendered in a `SVG` renderer.
12872		return (this.options.preferCanvas && canvas$1(options)) || svg$1(options);
12873	}
12874});
12875
12876/*
12877 * L.Rectangle extends Polygon and creates a rectangle when passed a LatLngBounds object.
12878 */
12879
12880/*
12881 * @class Rectangle
12882 * @aka L.Rectangle
12883 * @inherits Polygon
12884 *
12885 * A class for drawing rectangle overlays on a map. Extends `Polygon`.
12886 *
12887 * @example
12888 *
12889 * ```js
12890 * // define rectangle geographical bounds
12891 * var bounds = [[54.559322, -5.767822], [56.1210604, -3.021240]];
12892 *
12893 * // create an orange rectangle
12894 * L.rectangle(bounds, {color: "#ff7800", weight: 1}).addTo(map);
12895 *
12896 * // zoom the map to the rectangle bounds
12897 * map.fitBounds(bounds);
12898 * ```
12899 *
12900 */
12901
12902
12903var Rectangle = Polygon.extend({
12904	initialize: function (latLngBounds, options) {
12905		Polygon.prototype.initialize.call(this, this._boundsToLatLngs(latLngBounds), options);
12906	},
12907
12908	// @method setBounds(latLngBounds: LatLngBounds): this
12909	// Redraws the rectangle with the passed bounds.
12910	setBounds: function (latLngBounds) {
12911		return this.setLatLngs(this._boundsToLatLngs(latLngBounds));
12912	},
12913
12914	_boundsToLatLngs: function (latLngBounds) {
12915		latLngBounds = toLatLngBounds(latLngBounds);
12916		return [
12917			latLngBounds.getSouthWest(),
12918			latLngBounds.getNorthWest(),
12919			latLngBounds.getNorthEast(),
12920			latLngBounds.getSouthEast()
12921		];
12922	}
12923});
12924
12925
12926// @factory L.rectangle(latLngBounds: LatLngBounds, options?: Polyline options)
12927function rectangle(latLngBounds, options) {
12928	return new Rectangle(latLngBounds, options);
12929}
12930
12931SVG.create = create$2;
12932SVG.pointsToPath = pointsToPath;
12933
12934GeoJSON.geometryToLayer = geometryToLayer;
12935GeoJSON.coordsToLatLng = coordsToLatLng;
12936GeoJSON.coordsToLatLngs = coordsToLatLngs;
12937GeoJSON.latLngToCoords = latLngToCoords;
12938GeoJSON.latLngsToCoords = latLngsToCoords;
12939GeoJSON.getFeature = getFeature;
12940GeoJSON.asFeature = asFeature;
12941
12942/*
12943 * L.Handler.BoxZoom is used to add shift-drag zoom interaction to the map
12944 * (zoom to a selected bounding box), enabled by default.
12945 */
12946
12947// @namespace Map
12948// @section Interaction Options
12949Map.mergeOptions({
12950	// @option boxZoom: Boolean = true
12951	// Whether the map can be zoomed to a rectangular area specified by
12952	// dragging the mouse while pressing the shift key.
12953	boxZoom: true
12954});
12955
12956var BoxZoom = Handler.extend({
12957	initialize: function (map) {
12958		this._map = map;
12959		this._container = map._container;
12960		this._pane = map._panes.overlayPane;
12961		this._resetStateTimeout = 0;
12962		map.on('unload', this._destroy, this);
12963	},
12964
12965	addHooks: function () {
12966		on(this._container, 'mousedown', this._onMouseDown, this);
12967	},
12968
12969	removeHooks: function () {
12970		off(this._container, 'mousedown', this._onMouseDown, this);
12971	},
12972
12973	moved: function () {
12974		return this._moved;
12975	},
12976
12977	_destroy: function () {
12978		remove(this._pane);
12979		delete this._pane;
12980	},
12981
12982	_resetState: function () {
12983		this._resetStateTimeout = 0;
12984		this._moved = false;
12985	},
12986
12987	_clearDeferredResetState: function () {
12988		if (this._resetStateTimeout !== 0) {
12989			clearTimeout(this._resetStateTimeout);
12990			this._resetStateTimeout = 0;
12991		}
12992	},
12993
12994	_onMouseDown: function (e) {
12995		if (!e.shiftKey || ((e.which !== 1) && (e.button !== 1))) { return false; }
12996
12997		// Clear the deferred resetState if it hasn't executed yet, otherwise it
12998		// will interrupt the interaction and orphan a box element in the container.
12999		this._clearDeferredResetState();
13000		this._resetState();
13001
13002		disableTextSelection();
13003		disableImageDrag();
13004
13005		this._startPoint = this._map.mouseEventToContainerPoint(e);
13006
13007		on(document, {
13008			contextmenu: stop,
13009			mousemove: this._onMouseMove,
13010			mouseup: this._onMouseUp,
13011			keydown: this._onKeyDown
13012		}, this);
13013	},
13014
13015	_onMouseMove: function (e) {
13016		if (!this._moved) {
13017			this._moved = true;
13018
13019			this._box = create$1('div', 'leaflet-zoom-box', this._container);
13020			addClass(this._container, 'leaflet-crosshair');
13021
13022			this._map.fire('boxzoomstart');
13023		}
13024
13025		this._point = this._map.mouseEventToContainerPoint(e);
13026
13027		var bounds = new Bounds(this._point, this._startPoint),
13028		    size = bounds.getSize();
13029
13030		setPosition(this._box, bounds.min);
13031
13032		this._box.style.width  = size.x + 'px';
13033		this._box.style.height = size.y + 'px';
13034	},
13035
13036	_finish: function () {
13037		if (this._moved) {
13038			remove(this._box);
13039			removeClass(this._container, 'leaflet-crosshair');
13040		}
13041
13042		enableTextSelection();
13043		enableImageDrag();
13044
13045		off(document, {
13046			contextmenu: stop,
13047			mousemove: this._onMouseMove,
13048			mouseup: this._onMouseUp,
13049			keydown: this._onKeyDown
13050		}, this);
13051	},
13052
13053	_onMouseUp: function (e) {
13054		if ((e.which !== 1) && (e.button !== 1)) { return; }
13055
13056		this._finish();
13057
13058		if (!this._moved) { return; }
13059		// Postpone to next JS tick so internal click event handling
13060		// still see it as "moved".
13061		this._clearDeferredResetState();
13062		this._resetStateTimeout = setTimeout(bind(this._resetState, this), 0);
13063
13064		var bounds = new LatLngBounds(
13065		        this._map.containerPointToLatLng(this._startPoint),
13066		        this._map.containerPointToLatLng(this._point));
13067
13068		this._map
13069			.fitBounds(bounds)
13070			.fire('boxzoomend', {boxZoomBounds: bounds});
13071	},
13072
13073	_onKeyDown: function (e) {
13074		if (e.keyCode === 27) {
13075			this._finish();
13076		}
13077	}
13078});
13079
13080// @section Handlers
13081// @property boxZoom: Handler
13082// Box (shift-drag with mouse) zoom handler.
13083Map.addInitHook('addHandler', 'boxZoom', BoxZoom);
13084
13085/*
13086 * L.Handler.DoubleClickZoom is used to handle double-click zoom on the map, enabled by default.
13087 */
13088
13089// @namespace Map
13090// @section Interaction Options
13091
13092Map.mergeOptions({
13093	// @option doubleClickZoom: Boolean|String = true
13094	// Whether the map can be zoomed in by double clicking on it and
13095	// zoomed out by double clicking while holding shift. If passed
13096	// `'center'`, double-click zoom will zoom to the center of the
13097	//  view regardless of where the mouse was.
13098	doubleClickZoom: true
13099});
13100
13101var DoubleClickZoom = Handler.extend({
13102	addHooks: function () {
13103		this._map.on('dblclick', this._onDoubleClick, this);
13104	},
13105
13106	removeHooks: function () {
13107		this._map.off('dblclick', this._onDoubleClick, this);
13108	},
13109
13110	_onDoubleClick: function (e) {
13111		var map = this._map,
13112		    oldZoom = map.getZoom(),
13113		    delta = map.options.zoomDelta,
13114		    zoom = e.originalEvent.shiftKey ? oldZoom - delta : oldZoom + delta;
13115
13116		if (map.options.doubleClickZoom === 'center') {
13117			map.setZoom(zoom);
13118		} else {
13119			map.setZoomAround(e.containerPoint, zoom);
13120		}
13121	}
13122});
13123
13124// @section Handlers
13125//
13126// Map properties include interaction handlers that allow you to control
13127// interaction behavior in runtime, enabling or disabling certain features such
13128// as dragging or touch zoom (see `Handler` methods). For example:
13129//
13130// ```js
13131// map.doubleClickZoom.disable();
13132// ```
13133//
13134// @property doubleClickZoom: Handler
13135// Double click zoom handler.
13136Map.addInitHook('addHandler', 'doubleClickZoom', DoubleClickZoom);
13137
13138/*
13139 * L.Handler.MapDrag is used to make the map draggable (with panning inertia), enabled by default.
13140 */
13141
13142// @namespace Map
13143// @section Interaction Options
13144Map.mergeOptions({
13145	// @option dragging: Boolean = true
13146	// Whether the map be draggable with mouse/touch or not.
13147	dragging: true,
13148
13149	// @section Panning Inertia Options
13150	// @option inertia: Boolean = *
13151	// If enabled, panning of the map will have an inertia effect where
13152	// the map builds momentum while dragging and continues moving in
13153	// the same direction for some time. Feels especially nice on touch
13154	// devices. Enabled by default unless running on old Android devices.
13155	inertia: !android23,
13156
13157	// @option inertiaDeceleration: Number = 3000
13158	// The rate with which the inertial movement slows down, in pixels/second².
13159	inertiaDeceleration: 3400, // px/s^2
13160
13161	// @option inertiaMaxSpeed: Number = Infinity
13162	// Max speed of the inertial movement, in pixels/second.
13163	inertiaMaxSpeed: Infinity, // px/s
13164
13165	// @option easeLinearity: Number = 0.2
13166	easeLinearity: 0.2,
13167
13168	// TODO refactor, move to CRS
13169	// @option worldCopyJump: Boolean = false
13170	// With this option enabled, the map tracks when you pan to another "copy"
13171	// of the world and seamlessly jumps to the original one so that all overlays
13172	// like markers and vector layers are still visible.
13173	worldCopyJump: false,
13174
13175	// @option maxBoundsViscosity: Number = 0.0
13176	// If `maxBounds` is set, this option will control how solid the bounds
13177	// are when dragging the map around. The default value of `0.0` allows the
13178	// user to drag outside the bounds at normal speed, higher values will
13179	// slow down map dragging outside bounds, and `1.0` makes the bounds fully
13180	// solid, preventing the user from dragging outside the bounds.
13181	maxBoundsViscosity: 0.0
13182});
13183
13184var Drag = Handler.extend({
13185	addHooks: function () {
13186		if (!this._draggable) {
13187			var map = this._map;
13188
13189			this._draggable = new Draggable(map._mapPane, map._container);
13190
13191			this._draggable.on({
13192				dragstart: this._onDragStart,
13193				drag: this._onDrag,
13194				dragend: this._onDragEnd
13195			}, this);
13196
13197			this._draggable.on('predrag', this._onPreDragLimit, this);
13198			if (map.options.worldCopyJump) {
13199				this._draggable.on('predrag', this._onPreDragWrap, this);
13200				map.on('zoomend', this._onZoomEnd, this);
13201
13202				map.whenReady(this._onZoomEnd, this);
13203			}
13204		}
13205		addClass(this._map._container, 'leaflet-grab leaflet-touch-drag');
13206		this._draggable.enable();
13207		this._positions = [];
13208		this._times = [];
13209	},
13210
13211	removeHooks: function () {
13212		removeClass(this._map._container, 'leaflet-grab');
13213		removeClass(this._map._container, 'leaflet-touch-drag');
13214		this._draggable.disable();
13215	},
13216
13217	moved: function () {
13218		return this._draggable && this._draggable._moved;
13219	},
13220
13221	moving: function () {
13222		return this._draggable && this._draggable._moving;
13223	},
13224
13225	_onDragStart: function () {
13226		var map = this._map;
13227
13228		map._stop();
13229		if (this._map.options.maxBounds && this._map.options.maxBoundsViscosity) {
13230			var bounds = toLatLngBounds(this._map.options.maxBounds);
13231
13232			this._offsetLimit = toBounds(
13233				this._map.latLngToContainerPoint(bounds.getNorthWest()).multiplyBy(-1),
13234				this._map.latLngToContainerPoint(bounds.getSouthEast()).multiplyBy(-1)
13235					.add(this._map.getSize()));
13236
13237			this._viscosity = Math.min(1.0, Math.max(0.0, this._map.options.maxBoundsViscosity));
13238		} else {
13239			this._offsetLimit = null;
13240		}
13241
13242		map
13243		    .fire('movestart')
13244		    .fire('dragstart');
13245
13246		if (map.options.inertia) {
13247			this._positions = [];
13248			this._times = [];
13249		}
13250	},
13251
13252	_onDrag: function (e) {
13253		if (this._map.options.inertia) {
13254			var time = this._lastTime = +new Date(),
13255			    pos = this._lastPos = this._draggable._absPos || this._draggable._newPos;
13256
13257			this._positions.push(pos);
13258			this._times.push(time);
13259
13260			this._prunePositions(time);
13261		}
13262
13263		this._map
13264		    .fire('move', e)
13265		    .fire('drag', e);
13266	},
13267
13268	_prunePositions: function (time) {
13269		while (this._positions.length > 1 && time - this._times[0] > 50) {
13270			this._positions.shift();
13271			this._times.shift();
13272		}
13273	},
13274
13275	_onZoomEnd: function () {
13276		var pxCenter = this._map.getSize().divideBy(2),
13277		    pxWorldCenter = this._map.latLngToLayerPoint([0, 0]);
13278
13279		this._initialWorldOffset = pxWorldCenter.subtract(pxCenter).x;
13280		this._worldWidth = this._map.getPixelWorldBounds().getSize().x;
13281	},
13282
13283	_viscousLimit: function (value, threshold) {
13284		return value - (value - threshold) * this._viscosity;
13285	},
13286
13287	_onPreDragLimit: function () {
13288		if (!this._viscosity || !this._offsetLimit) { return; }
13289
13290		var offset = this._draggable._newPos.subtract(this._draggable._startPos);
13291
13292		var limit = this._offsetLimit;
13293		if (offset.x < limit.min.x) { offset.x = this._viscousLimit(offset.x, limit.min.x); }
13294		if (offset.y < limit.min.y) { offset.y = this._viscousLimit(offset.y, limit.min.y); }
13295		if (offset.x > limit.max.x) { offset.x = this._viscousLimit(offset.x, limit.max.x); }
13296		if (offset.y > limit.max.y) { offset.y = this._viscousLimit(offset.y, limit.max.y); }
13297
13298		this._draggable._newPos = this._draggable._startPos.add(offset);
13299	},
13300
13301	_onPreDragWrap: function () {
13302		// TODO refactor to be able to adjust map pane position after zoom
13303		var worldWidth = this._worldWidth,
13304		    halfWidth = Math.round(worldWidth / 2),
13305		    dx = this._initialWorldOffset,
13306		    x = this._draggable._newPos.x,
13307		    newX1 = (x - halfWidth + dx) % worldWidth + halfWidth - dx,
13308		    newX2 = (x + halfWidth + dx) % worldWidth - halfWidth - dx,
13309		    newX = Math.abs(newX1 + dx) < Math.abs(newX2 + dx) ? newX1 : newX2;
13310
13311		this._draggable._absPos = this._draggable._newPos.clone();
13312		this._draggable._newPos.x = newX;
13313	},
13314
13315	_onDragEnd: function (e) {
13316		var map = this._map,
13317		    options = map.options,
13318
13319		    noInertia = !options.inertia || this._times.length < 2;
13320
13321		map.fire('dragend', e);
13322
13323		if (noInertia) {
13324			map.fire('moveend');
13325
13326		} else {
13327			this._prunePositions(+new Date());
13328
13329			var direction = this._lastPos.subtract(this._positions[0]),
13330			    duration = (this._lastTime - this._times[0]) / 1000,
13331			    ease = options.easeLinearity,
13332
13333			    speedVector = direction.multiplyBy(ease / duration),
13334			    speed = speedVector.distanceTo([0, 0]),
13335
13336			    limitedSpeed = Math.min(options.inertiaMaxSpeed, speed),
13337			    limitedSpeedVector = speedVector.multiplyBy(limitedSpeed / speed),
13338
13339			    decelerationDuration = limitedSpeed / (options.inertiaDeceleration * ease),
13340			    offset = limitedSpeedVector.multiplyBy(-decelerationDuration / 2).round();
13341
13342			if (!offset.x && !offset.y) {
13343				map.fire('moveend');
13344
13345			} else {
13346				offset = map._limitOffset(offset, map.options.maxBounds);
13347
13348				requestAnimFrame(function () {
13349					map.panBy(offset, {
13350						duration: decelerationDuration,
13351						easeLinearity: ease,
13352						noMoveStart: true,
13353						animate: true
13354					});
13355				});
13356			}
13357		}
13358	}
13359});
13360
13361// @section Handlers
13362// @property dragging: Handler
13363// Map dragging handler (by both mouse and touch).
13364Map.addInitHook('addHandler', 'dragging', Drag);
13365
13366/*
13367 * L.Map.Keyboard is handling keyboard interaction with the map, enabled by default.
13368 */
13369
13370// @namespace Map
13371// @section Keyboard Navigation Options
13372Map.mergeOptions({
13373	// @option keyboard: Boolean = true
13374	// Makes the map focusable and allows users to navigate the map with keyboard
13375	// arrows and `+`/`-` keys.
13376	keyboard: true,
13377
13378	// @option keyboardPanDelta: Number = 80
13379	// Amount of pixels to pan when pressing an arrow key.
13380	keyboardPanDelta: 80
13381});
13382
13383var Keyboard = Handler.extend({
13384
13385	keyCodes: {
13386		left:    [37],
13387		right:   [39],
13388		down:    [40],
13389		up:      [38],
13390		zoomIn:  [187, 107, 61, 171],
13391		zoomOut: [189, 109, 54, 173]
13392	},
13393
13394	initialize: function (map) {
13395		this._map = map;
13396
13397		this._setPanDelta(map.options.keyboardPanDelta);
13398		this._setZoomDelta(map.options.zoomDelta);
13399	},
13400
13401	addHooks: function () {
13402		var container = this._map._container;
13403
13404		// make the container focusable by tabbing
13405		if (container.tabIndex <= 0) {
13406			container.tabIndex = '0';
13407		}
13408
13409		on(container, {
13410			focus: this._onFocus,
13411			blur: this._onBlur,
13412			mousedown: this._onMouseDown
13413		}, this);
13414
13415		this._map.on({
13416			focus: this._addHooks,
13417			blur: this._removeHooks
13418		}, this);
13419	},
13420
13421	removeHooks: function () {
13422		this._removeHooks();
13423
13424		off(this._map._container, {
13425			focus: this._onFocus,
13426			blur: this._onBlur,
13427			mousedown: this._onMouseDown
13428		}, this);
13429
13430		this._map.off({
13431			focus: this._addHooks,
13432			blur: this._removeHooks
13433		}, this);
13434	},
13435
13436	_onMouseDown: function () {
13437		if (this._focused) { return; }
13438
13439		var body = document.body,
13440		    docEl = document.documentElement,
13441		    top = body.scrollTop || docEl.scrollTop,
13442		    left = body.scrollLeft || docEl.scrollLeft;
13443
13444		this._map._container.focus();
13445
13446		window.scrollTo(left, top);
13447	},
13448
13449	_onFocus: function () {
13450		this._focused = true;
13451		this._map.fire('focus');
13452	},
13453
13454	_onBlur: function () {
13455		this._focused = false;
13456		this._map.fire('blur');
13457	},
13458
13459	_setPanDelta: function (panDelta) {
13460		var keys = this._panKeys = {},
13461		    codes = this.keyCodes,
13462		    i, len;
13463
13464		for (i = 0, len = codes.left.length; i < len; i++) {
13465			keys[codes.left[i]] = [-1 * panDelta, 0];
13466		}
13467		for (i = 0, len = codes.right.length; i < len; i++) {
13468			keys[codes.right[i]] = [panDelta, 0];
13469		}
13470		for (i = 0, len = codes.down.length; i < len; i++) {
13471			keys[codes.down[i]] = [0, panDelta];
13472		}
13473		for (i = 0, len = codes.up.length; i < len; i++) {
13474			keys[codes.up[i]] = [0, -1 * panDelta];
13475		}
13476	},
13477
13478	_setZoomDelta: function (zoomDelta) {
13479		var keys = this._zoomKeys = {},
13480		    codes = this.keyCodes,
13481		    i, len;
13482
13483		for (i = 0, len = codes.zoomIn.length; i < len; i++) {
13484			keys[codes.zoomIn[i]] = zoomDelta;
13485		}
13486		for (i = 0, len = codes.zoomOut.length; i < len; i++) {
13487			keys[codes.zoomOut[i]] = -zoomDelta;
13488		}
13489	},
13490
13491	_addHooks: function () {
13492		on(document, 'keydown', this._onKeyDown, this);
13493	},
13494
13495	_removeHooks: function () {
13496		off(document, 'keydown', this._onKeyDown, this);
13497	},
13498
13499	_onKeyDown: function (e) {
13500		if (e.altKey || e.ctrlKey || e.metaKey) { return; }
13501
13502		var key = e.keyCode,
13503		    map = this._map,
13504		    offset;
13505
13506		if (key in this._panKeys) {
13507			if (!map._panAnim || !map._panAnim._inProgress) {
13508				offset = this._panKeys[key];
13509				if (e.shiftKey) {
13510					offset = toPoint(offset).multiplyBy(3);
13511				}
13512
13513				map.panBy(offset);
13514
13515				if (map.options.maxBounds) {
13516					map.panInsideBounds(map.options.maxBounds);
13517				}
13518			}
13519		} else if (key in this._zoomKeys) {
13520			map.setZoom(map.getZoom() + (e.shiftKey ? 3 : 1) * this._zoomKeys[key]);
13521
13522		} else if (key === 27 && map._popup && map._popup.options.closeOnEscapeKey) {
13523			map.closePopup();
13524
13525		} else {
13526			return;
13527		}
13528
13529		stop(e);
13530	}
13531});
13532
13533// @section Handlers
13534// @section Handlers
13535// @property keyboard: Handler
13536// Keyboard navigation handler.
13537Map.addInitHook('addHandler', 'keyboard', Keyboard);
13538
13539/*
13540 * L.Handler.ScrollWheelZoom is used by L.Map to enable mouse scroll wheel zoom on the map.
13541 */
13542
13543// @namespace Map
13544// @section Interaction Options
13545Map.mergeOptions({
13546	// @section Mousewheel options
13547	// @option scrollWheelZoom: Boolean|String = true
13548	// Whether the map can be zoomed by using the mouse wheel. If passed `'center'`,
13549	// it will zoom to the center of the view regardless of where the mouse was.
13550	scrollWheelZoom: true,
13551
13552	// @option wheelDebounceTime: Number = 40
13553	// Limits the rate at which a wheel can fire (in milliseconds). By default
13554	// user can't zoom via wheel more often than once per 40 ms.
13555	wheelDebounceTime: 40,
13556
13557	// @option wheelPxPerZoomLevel: Number = 60
13558	// How many scroll pixels (as reported by [L.DomEvent.getWheelDelta](#domevent-getwheeldelta))
13559	// mean a change of one full zoom level. Smaller values will make wheel-zooming
13560	// faster (and vice versa).
13561	wheelPxPerZoomLevel: 60
13562});
13563
13564var ScrollWheelZoom = Handler.extend({
13565	addHooks: function () {
13566		on(this._map._container, 'mousewheel', this._onWheelScroll, this);
13567
13568		this._delta = 0;
13569	},
13570
13571	removeHooks: function () {
13572		off(this._map._container, 'mousewheel', this._onWheelScroll, this);
13573	},
13574
13575	_onWheelScroll: function (e) {
13576		var delta = getWheelDelta(e);
13577
13578		var debounce = this._map.options.wheelDebounceTime;
13579
13580		this._delta += delta;
13581		this._lastMousePos = this._map.mouseEventToContainerPoint(e);
13582
13583		if (!this._startTime) {
13584			this._startTime = +new Date();
13585		}
13586
13587		var left = Math.max(debounce - (+new Date() - this._startTime), 0);
13588
13589		clearTimeout(this._timer);
13590		this._timer = setTimeout(bind(this._performZoom, this), left);
13591
13592		stop(e);
13593	},
13594
13595	_performZoom: function () {
13596		var map = this._map,
13597		    zoom = map.getZoom(),
13598		    snap = this._map.options.zoomSnap || 0;
13599
13600		map._stop(); // stop panning and fly animations if any
13601
13602		// map the delta with a sigmoid function to -4..4 range leaning on -1..1
13603		var d2 = this._delta / (this._map.options.wheelPxPerZoomLevel * 4),
13604		    d3 = 4 * Math.log(2 / (1 + Math.exp(-Math.abs(d2)))) / Math.LN2,
13605		    d4 = snap ? Math.ceil(d3 / snap) * snap : d3,
13606		    delta = map._limitZoom(zoom + (this._delta > 0 ? d4 : -d4)) - zoom;
13607
13608		this._delta = 0;
13609		this._startTime = null;
13610
13611		if (!delta) { return; }
13612
13613		if (map.options.scrollWheelZoom === 'center') {
13614			map.setZoom(zoom + delta);
13615		} else {
13616			map.setZoomAround(this._lastMousePos, zoom + delta);
13617		}
13618	}
13619});
13620
13621// @section Handlers
13622// @property scrollWheelZoom: Handler
13623// Scroll wheel zoom handler.
13624Map.addInitHook('addHandler', 'scrollWheelZoom', ScrollWheelZoom);
13625
13626/*
13627 * L.Map.Tap is used to enable mobile hacks like quick taps and long hold.
13628 */
13629
13630// @namespace Map
13631// @section Interaction Options
13632Map.mergeOptions({
13633	// @section Touch interaction options
13634	// @option tap: Boolean = true
13635	// Enables mobile hacks for supporting instant taps (fixing 200ms click
13636	// delay on iOS/Android) and touch holds (fired as `contextmenu` events).
13637	tap: true,
13638
13639	// @option tapTolerance: Number = 15
13640	// The max number of pixels a user can shift his finger during touch
13641	// for it to be considered a valid tap.
13642	tapTolerance: 15
13643});
13644
13645var Tap = Handler.extend({
13646	addHooks: function () {
13647		on(this._map._container, 'touchstart', this._onDown, this);
13648	},
13649
13650	removeHooks: function () {
13651		off(this._map._container, 'touchstart', this._onDown, this);
13652	},
13653
13654	_onDown: function (e) {
13655		if (!e.touches) { return; }
13656
13657		preventDefault(e);
13658
13659		this._fireClick = true;
13660
13661		// don't simulate click or track longpress if more than 1 touch
13662		if (e.touches.length > 1) {
13663			this._fireClick = false;
13664			clearTimeout(this._holdTimeout);
13665			return;
13666		}
13667
13668		var first = e.touches[0],
13669		    el = first.target;
13670
13671		this._startPos = this._newPos = new Point(first.clientX, first.clientY);
13672
13673		// if touching a link, highlight it
13674		if (el.tagName && el.tagName.toLowerCase() === 'a') {
13675			addClass(el, 'leaflet-active');
13676		}
13677
13678		// simulate long hold but setting a timeout
13679		this._holdTimeout = setTimeout(bind(function () {
13680			if (this._isTapValid()) {
13681				this._fireClick = false;
13682				this._onUp();
13683				this._simulateEvent('contextmenu', first);
13684			}
13685		}, this), 1000);
13686
13687		this._simulateEvent('mousedown', first);
13688
13689		on(document, {
13690			touchmove: this._onMove,
13691			touchend: this._onUp
13692		}, this);
13693	},
13694
13695	_onUp: function (e) {
13696		clearTimeout(this._holdTimeout);
13697
13698		off(document, {
13699			touchmove: this._onMove,
13700			touchend: this._onUp
13701		}, this);
13702
13703		if (this._fireClick && e && e.changedTouches) {
13704
13705			var first = e.changedTouches[0],
13706			    el = first.target;
13707
13708			if (el && el.tagName && el.tagName.toLowerCase() === 'a') {
13709				removeClass(el, 'leaflet-active');
13710			}
13711
13712			this._simulateEvent('mouseup', first);
13713
13714			// simulate click if the touch didn't move too much
13715			if (this._isTapValid()) {
13716				this._simulateEvent('click', first);
13717			}
13718		}
13719	},
13720
13721	_isTapValid: function () {
13722		return this._newPos.distanceTo(this._startPos) <= this._map.options.tapTolerance;
13723	},
13724
13725	_onMove: function (e) {
13726		var first = e.touches[0];
13727		this._newPos = new Point(first.clientX, first.clientY);
13728		this._simulateEvent('mousemove', first);
13729	},
13730
13731	_simulateEvent: function (type, e) {
13732		var simulatedEvent = document.createEvent('MouseEvents');
13733
13734		simulatedEvent._simulated = true;
13735		e.target._simulatedClick = true;
13736
13737		simulatedEvent.initMouseEvent(
13738		        type, true, true, window, 1,
13739		        e.screenX, e.screenY,
13740		        e.clientX, e.clientY,
13741		        false, false, false, false, 0, null);
13742
13743		e.target.dispatchEvent(simulatedEvent);
13744	}
13745});
13746
13747// @section Handlers
13748// @property tap: Handler
13749// Mobile touch hacks (quick tap and touch hold) handler.
13750if (touch && !pointer) {
13751	Map.addInitHook('addHandler', 'tap', Tap);
13752}
13753
13754/*
13755 * L.Handler.TouchZoom is used by L.Map to add pinch zoom on supp
vendor: 4,276 bytes, lines 13755-13895
13755orted mobile browsers.
13756 */
13757
13758// @namespace Map
13759// @section Interaction Options
13760Map.mergeOptions({
13761	// @section Touch interaction options
13762	// @option touchZoom: Boolean|String = *
13763	// Whether the map can be zoomed by touch-dragging with two fingers. If
13764	// passed `'center'`, it will zoom to the center of the view regardless of
13765	// where the touch events (fingers) were. Enabled for touch-capable web
13766	// browsers except for old Androids.
13767	touchZoom: touch && !android23,
13768
13769	// @option bounceAtZoomLimits: Boolean = true
13770	// Set it to false if you don't want the map to zoom beyond min/max zoom
13771	// and then bounce back when pinch-zooming.
13772	bounceAtZoomLimits: true
13773});
13774
13775var TouchZoom = Handler.extend({
13776	addHooks: function () {
13777		addClass(this._map._container, 'leaflet-touch-zoom');
13778		on(this._map._container, 'touchstart', this._onTouchStart, this);
13779	},
13780
13781	removeHooks: function () {
13782		removeClass(this._map._container, 'leaflet-touch-zoom');
13783		off(this._map._container, 'touchstart', this._onTouchStart, this);
13784	},
13785
13786	_onTouchStart: function (e) {
13787		var map = this._map;
13788		if (!e.touches || e.touches.length !== 2 || map._animatingZoom || this._zooming) { return; }
13789
13790		var p1 = map.mouseEventToContainerPoint(e.touches[0]),
13791		    p2 = map.mouseEventToContainerPoint(e.touches[1]);
13792
13793		this._centerPoint = map.getSize()._divideBy(2);
13794		this._startLatLng = map.containerPointToLatLng(this._centerPoint);
13795		if (map.options.touchZoom !== 'center') {
13796			this._pinchStartLatLng = map.containerPointToLatLng(p1.add(p2)._divideBy(2));
13797		}
13798
13799		this._startDist = p1.distanceTo(p2);
13800		this._startZoom = map.getZoom();
13801
13802		this._moved = false;
13803		this._zooming = true;
13804
13805		map._stop();
13806
13807		on(document, 'touchmove', this._onTouchMove, this);
13808		on(document, 'touchend', this._onTouchEnd, this);
13809
13810		preventDefault(e);
13811	},
13812
13813	_onTouchMove: function (e) {
13814		if (!e.touches || e.touches.length !== 2 || !this._zooming) { return; }
13815
13816		var map = this._map,
13817		    p1 = map.mouseEventToContainerPoint(e.touches[0]),
13818		    p2 = map.mouseEventToContainerPoint(e.touches[1]),
13819		    scale = p1.distanceTo(p2) / this._startDist;
13820
13821		this._zoom = map.getScaleZoom(scale, this._startZoom);
13822
13823		if (!map.options.bounceAtZoomLimits && (
13824			(this._zoom < map.getMinZoom() && scale < 1) ||
13825			(this._zoom > map.getMaxZoom() && scale > 1))) {
13826			this._zoom = map._limitZoom(this._zoom);
13827		}
13828
13829		if (map.options.touchZoom === 'center') {
13830			this._center = this._startLatLng;
13831			if (scale === 1) { return; }
13832		} else {
13833			// Get delta from pinch to center, so centerLatLng is delta applied to initial pinchLatLng
13834			var delta = p1._add(p2)._divideBy(2)._subtract(this._centerPoint);
13835			if (scale === 1 && delta.x === 0 && delta.y === 0) { return; }
13836			this._center = map.unproject(map.project(this._pinchStartLatLng, this._zoom).subtract(delta), this._zoom);
13837		}
13838
13839		if (!this._moved) {
13840			map._moveStart(true, false);
13841			this._moved = true;
13842		}
13843
13844		cancelAnimFrame(this._animRequest);
13845
13846		var moveFn = bind(map._move, map, this._center, this._zoom, {pinch: true, round: false});
13847		this._animRequest = requestAnimFrame(moveFn, this, true);
13848
13849		preventDefault(e);
13850	},
13851
13852	_onTouchEnd: function () {
13853		if (!this._moved || !this._zooming) {
13854			this._zooming = false;
13855			return;
13856		}
13857
13858		this._zooming = false;
13859		cancelAnimFrame(this._animRequest);
13860
13861		off(document, 'touchmove', this._onTouchMove);
13862		off(document, 'touchend', this._onTouchEnd);
13863
13864		// Pinch updates GridLayers' levels only when zoomSnap is off, so zoomSnap becomes noUpdate.
13865		if (this._map.options.zoomAnimation) {
13866			this._map._animateZoom(this._center, this._map._limitZoom(this._zoom), true, this._map.options.zoomSnap);
13867		} else {
13868			this._map._resetView(this._center, this._map._limitZoom(this._zoom));
13869		}
13870	}
13871});
13872
13873// @section Handlers
13874// @property touchZoom: Handler
13875// Touch zoom handler.
13876Map.addInitHook('addHandler', 'touchZoom', TouchZoom);
13877
13878Map.BoxZoom = BoxZoom;
13879Map.DoubleClickZoom = DoubleClickZoom;
13880Map.Drag = Drag;
13881Map.Keyboard = Keyboard;
13882Map.ScrollWheelZoom = ScrollWheelZoom;
13883Map.Tap = Tap;
13884Map.TouchZoom = TouchZoom;
13885
13886Object.freeze = freeze;
13887
13888exports.version = version;
13889exports.Control = Control;
13890exports.control = control;
13891exports.Browser = Browser;
13892exports.Evented = Evented;
13893exports.Mixin = Mixin;
13894exports.Util = Util;
13895exports.Class = Class;
13896exports.Handler = Handler;
13897exports.extend = extend;
13898exports.bind = bind;
13899exports.stamp = stamp;
13900exports.setOptions = setOptions;
13901exports.DomEvent = DomEvent;
13902exports.DomUtil = DomUtil;
13903exports.PosAnimation = PosAnimation;
13904exports.Draggable = Draggable;
13905exports.LineUtil = LineUtil;
13906exports.PolyUtil = PolyUtil;
13907exports.Point = Point;
13908exports.point = toPoint;
13909exports.Bounds = Bounds;
13910exports.bounds = toBounds;
13911exports.Transformation = Transformation;
13912exports.transformation = toTransformation;
13913exports.Projection = index;
13914exports.LatLng = LatLng;
13915exports.latLng = toLatLng;
13916exports.LatLngBounds = LatLngBounds;
13917exports.latLngBounds = toLatLngBounds;
13918exports.CRS = CRS;
13919exports.GeoJSON = GeoJSON;
13920exports.geoJSON = geoJSON;
13921exports.geoJson = geoJson;
13922exports.Layer = Layer;
13923exports.LayerGroup = LayerGroup;
13924exports.layerGroup = layerGroup;
13925exports.FeatureGroup = FeatureGroup;
13926exports.featureGroup = featureGroup;
13927exports.ImageOverlay = ImageOverlay;
13928exports.imageOverlay = imageOverlay;
13929exports.VideoOverlay = VideoOverlay;
13930exports.videoOverlay = videoOverlay;
13931exports.DivOverlay = DivOverlay;
13932exports.Popup = Popup;
13933exports.popup = popup;
13934exports.Tooltip = Tooltip;
13935exports.tooltip = tooltip;
13936exports.Icon = Icon;
13937exports.icon = icon;
13938exports.DivIcon = DivIcon;
13939exports.divIcon = divIcon;
13940exports.Marker = Marker;
13941exports.marker = marker;
13942exports.TileLayer = TileLayer;
13943exports.tileLayer = tileLayer;
13944exports.GridLayer = GridLayer;
13945exports.gridLayer = gridLayer;
13946exports.SVG = SVG;
13947exports.svg = svg$1;
13948exports.Renderer = Renderer;
13949exports.Canvas = Canvas;
13950exports.canvas = canvas$1;
13951exports.Path = Path;
13952exports.CircleMarker = CircleMarker;
13953exports.circleMarker = circleMarker;
13954exports.Circle = Circle;
13955exports.circle = circle;
13956exports.Polyline = Polyline;
13957exports.polyline = polyline;
13958exports.Polygon = Polygon;
13959exports.polygon = polygon;
13960exports.Rectangle = Rectangle;
13961exports.rectangle = rectangle;
13962exports.Map = Map;
13963exports.map = createMap;
13964
13965var oldL = window.L;
13966exports.noConflict = function() {
13967	window.L = oldL;
13968	return this;
13969}
13970
13971// Always export us to window global (see #2364)
13972window.L = exports;
13973
13974})));
13975//# sourceMappingURL=leaflet-src.js.map
13976
13977!function(r){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=r();else if("function"==typeof define&&define.amd)define([],r);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.omnivore=r()}}(function(){var r;return function r(e,t,n){function o(u,a){if(!t[u]){if(!e[u]){var s="function"==typeof require&&require;if(!a&&s)return s(u,!0);if(i)return i(u,!0);var f=new Error("Cannot find module '"+u+"'");throw f.code="MODULE_NOT_FOUND",f}var c=t[u]={exports:{}};e[u][0].call(c.exports,function(r){var t=e[u][1][r];return o(t?t:r)},c,c.exports,r,e,t,n)}return t[u].exports}for(var i="function"==typeof require&&require,u=0;u<n.length;u++)o(n[u]);return o}({1:[function(r,e,t){function n(r,e){"setGeoJSON"in r?r.setGeoJSON(e):"addData"in r&&r.addData(e)}function o(r,e,t){var o=t||L.geoJson();return y(r,function(r,e){return r?o.fire("error",{error:r}):(n(o,JSON.parse(e.responseText)),void o.fire("ready"))}),o}function i(r,e,t){function n(r,t){return r?o.fire("error",{error:r}):(l(t.responseText,e,o),void o.fire("ready"))}var o=t||L.geoJson();return y(r,n),o}function u(r,e,t){function n(r,t){function n(){i=!0}var i;return r?o.fire("error",{error:r}):(o.on("error",n),p(t.responseText,e,o),o.off("error",n),void(i||o.fire("ready")))}var o=t||L.geoJson();return y(r,n),o}function a(r,e,t){function n(r,t){function n(){i=!0}var i;return r?o.fire("error",{error:r}):(o.on("error",n),h(t.responseXML||t.responseText,e,o),o.off("error",n),void(i||o.fire("ready")))}var o=t||L.geoJson();return y(r,n),o}function s(r,e,t){function n(r,t){function n(){i=!0}var i;return r?o.fire("error",{error:r}):(o.on("error",n),g(t.responseXML||t.responseText,e,o),o.off("error",n),void(i||o.fire("ready")))}var o=t||L.geoJson();return y(r,n),o}function f(r,e,t){function n(r,t){return r?o.fire("error",{error:r}):(v(t.responseText,e,o),void o.fire("ready"))}var o=t||L.geoJson();return y(r,n),o}function c(r,e,t){function n(r,t){return r?o.fire("error",{error:r}):(d(t.responseText,e,o),void o.fire("ready"))}var o=t||L.geoJson();return y(r,n),o}function l(r,e,t){var o="string"==typeof r?JSON.parse(r):r;t=t||L.geoJson();for(var i in o.objects){var u=S.feature(o,o.objects[i]);u.features?n(t,u.features):n(t,u)}return t}function p(r,e,t){function o(r,e){return r?t.fire("error",{error:r}):void n(t,e)}return t=t||L.geoJson(),e=e||{},x.csv2geojson(r,e,o),t}function h(r,e,t){var o=m(r);
13977if(!o)return t.fire("error",{error:"Could not parse GPX"});t=t||L.geoJson();var i=T.gpx(o);return n(t,i),t}function g(r,e,t){var o=m(r);if(!o)return t.fire("error",{error:"Could not parse KML"});t=t||L.geoJson();var i=T.kml(o);return n(t,i),t}function d(r,e,t){t=t||L.geoJson(),e=e||{};for(var o=E.decode(r,e.precision),i={type:"LineString",coordinates:[]},u=0;u<o.length;u++)i.coordinates[u]=[o[u][1],o[u][0]];return n(t,i),t}function v(r,e,t){t=t||L.geoJson();var o=w(r);return n(t,o),t}function m(r){return"string"==typeof r?(new DOMParser).parseFromString(r,"text/xml"):r}var y=r("corslite"),x=r("csv2geojson"),w=r("wellknown"),E=r("polyline"),S=r("topojson"),T=r("togeojson");e.exports.polyline=c,e.exports.polyline.parse=d,e.exports.geojson=o,e.exports.topojson=i,e.exports.topojson.parse=l,e.exports.csv=u,e.exports.csv.parse=p,e.exports.gpx=a,e.exports.gpx.parse=h,e.exports.kml=s,e.exports.kml.parse=g,e.exports.wkt=f,e.exports.wkt.parse=v},{corslite:4,csv2geojson:5,polyline:8,togeojson:9,topojson:10,wellknown:11}],2:[function(r,e,t){},{}],3:[function(r,e,t){function n(){throw new Error("setTimeout has not been defined")}function o(){throw new Error("clearTimeout has not been defined")}function i(r){if(l===setTimeout)return setTimeout(r,0);if((l===n||!l)&&setTimeout)return l=setTimeout,setTimeout(r,0);try{return l(r,0)}catch(e){try{return l.call(null,r,0)}catch(e){return l.call(this,r,0)}}}function u(r){if(p===clearTimeout)return clearTimeout(r);if((p===o||!p)&&clearTimeout)return p=clearTimeout,clearTimeout(r);try{return p(r)}catch(e){try{return p.call(null,r)}catch(e){return p.call(this,r)}}}function a(){v&&g&&(v=!1,g.length?d=g.concat(d):m=-1,d.length&&s())}function s(){if(!v){var r=i(a);v=!0;for(var e=d.length;e;){for(g=d,d=[];++m<e;)g&&g[m].run();m=-1,e=d.length}g=null,v=!1,u(r)}}function f(r,e){this.fun=r,this.array=e}function c(){}var l,p,h=e.exports={};!function(){try{l="function"==typeof setTimeout?setTimeout:n}catch(r){l=n}try{p="function"==typeof clearTimeout?clearTimeout:o}catch(r){p=o}}();var g,d=[],v=!1,m=-1;h.nextTick=function(r){var e=new Array(arguments.length-1);if(arguments.length>1)for(var t=1;t<arguments.length;t++)e[t-1]=arguments[t];d.push(new f(r,e)),1!==d.length||v||i(s)},f.prototype.run=function(){this.fun.apply(null,this.array)},h.title="browser",h.browser=!0,h.env={},h.argv=[],h.version="",h.versions={},h.on=c,h.addListener=c,h.once=c,h.off=c,h.removeListener=c,h.removeAllListeners=c,h.emit=c,h.binding=function(r){throw new Error("process.binding is not supported")},h.cwd=function(){return"/"},h.chdir=function(r){throw new Error("process.chdir is not supported")},h.umask=function(){return 0}},{}],4:[function(r,e,t){function n(r,e,t){function n(r){return r>=200&&r<300||304===r}function o(){void 0===a.status||n(a.status)?e.call(a,null,a):e.call(a,a,null)}var i=!1;if("undefined"==typeof window.XMLHttpRequest)return e(Error("Browser not supported"));if("undefined"==typeof t){var u=r.match(/^\s*https?:\/\/[^\/]*/);t=u&&u[0]!==location.protocol+"//"+location.hostname+(location.port?":"+location.port:"")}var a=new window.XMLHttpRequest;if(t&&!("withCredentials"in a)){a=new window.XDomainRequest;var s=e;e=function(){if(i)s.apply(this,arguments);else{var r=this,e=arguments;setTimeout(function(){s.apply(r,e)},0)}}}return"onload"in a?a.onload=o:a.onreadystatechange=function(){4===a.readyState&&o()},a.onerror=function(r){e.call(this,r||!0,null),e=function(){}},a.onprogress=function(){},a.ontimeout=function(r){e.call(this,r,null),e=function(){}},a.onabort=function(r){e.call(this,r,null),e=function(){}},a.open("GET",r,!0),a.send(null),i=!0,a}"undefined"!=typeof e&&(e.exports=n)},{}],5:[function(r,e,t){"use strict";function n(r,e){var t,n,o;for(var i in r)n=i.match(e),n&&(!t||n[0].length/i.length>o)&&(o=n[0].length/i.length,t=i);return t}function o(r){return n(r,m)}function i(r){return n(r,y)}function u(r){return!!r.match(m)}function a(r){return!!r.match(y)}function s(r){return"object"==typeof r?Object.keys(r).length:0}function f(r){var e=[",",";","\t","|"],t=[];return e.forEach(function(e){var n=d.dsvFormat(e).parse(r);if(n.length>=1){for(var o=s(n[0]),i=0;i<n.length;i++)if(s(n[i])!==o)return;t.push({delimiter:e,arity:Object.keys(n[0]).length})}}),t.length?t.sort(function(r,e){return e.arity-r.arity})[0].delimiter:null}function c(r){return delete r.columns,r}function l(r){var e=f(r);return e?c(d.dsvFormat(e).parse(r)):null}function p(r,e,t){t||(t=e,e={}),e.delimiter=e.delimiter||",";var n=e.latfield||"",u=e.lonfield||"",a=e.crs||"",s=[],c={type:"FeatureCollection",features:s};if(""!==a&&(c.crs={type:"name",properties:{name:a}}),"auto"===e.delimiter&&"string"==typeof r&&(e.delimiter=f(r),!e.delimiter))return void t({type:"Error",message:"Could not autodetect delimiter"});var l="string"==typeof r?d.dsvFormat(e.delimiter).parse(r):r;if(!l.length)return void t(null,c);var p,h=[];n||(n=o(l[0])),u||(u=i(l[0]));var g=!n||!u;if(g){for(p=0;p<l.length;p++)s.push({type:"Feature",properties:l[p],geometry:null});return void t(h.length?h:null,c)}for(p=0;p<l.length;p++)if(void 0!==l[p][u]&&void 0!==l[p][n]){var m,y,x,w=l[p][u],L=l[p][n];x=v(w,"EW"),x&&(w=x),x=v(L,"NS"),x&&(L=x),m=parseFloat(w),y=parseFloat(L),isNaN(m)||isNaN(y)?h.push({message:"A row contained an invali
13977d value for latitude or longitude",row:l[p],index:p}):(e.includeLatLon||(delete l[p][u],delete l[p][n]),s.push({type:"Feature",properties:l[p],geometry:{type:"Point",coordinates:[parseFloat(m),parseFloat(y)]}}))}t(h.length?h:null,c)}function h(r){for(var e=r.features,t={type:"Feature",geometry:{type:"LineString",coordinates:[]}},n=0;n<e.length;n++)t.geometry.coordinates.push(e[n].geometry.coordinates);return t.properties=e.reduce(function(r,e){for(var t in e.properties)r[t]||(r[t]=[]),r[t].push(e.properties[t]);return r},{}),{type:"FeatureCollection",features:[t]}}function g(r){for(var e=r.features,t={type:"Feature",geometry:{type:"Polygon",coordinates:[[]]}},n=0;n<e.length;n++)t.geometry.coordinates[0].push(e[n].geometry.coordinates);return t.properties=e.reduce(function(r,e){for(var t in e.properties)r[t]||(r[t]=[]),r[t].push(e.properties[t]);return r},{}),{type:"FeatureCollection",features:[t]}}var d=r("d3-dsv"),v=r("sexagesimal"),m=/(Lat)(itude)?/gi,y=/(L)(on|ng)(gitude)?/i;e.exports={isLon:a,isLat:u,guessLatHeader:o,guessLonHeader:i,csv:d.csvParse,tsv:d.tsvParse,dsv:d,auto:l,csv2geojson:p,toLine:h,toPolygon:g}},{"d3-dsv":6,sexagesimal:7}],6:[function(e,t,n){!function(e,o){"object"==typeof n&&"undefined"!=typeof t?o(n):"function"==typeof r&&r.amd?r(["exports"],o):o(e.d3=e.d3||{})}(this,function(r){"use strict";function e(r){return new Function("d","return {"+r.map(function(r,e){return JSON.stringify(r)+": d["+e+"]"}).join(",")+"}")}function t(r,t){var n=e(r);return function(e,o){return t(n(e),o,r)}}function n(r){var e=Object.create(null),t=[];return r.forEach(function(r){for(var n in r)n in e||t.push(e[n]=n)}),t}function o(r){function o(r,n){var o,u,a=i(r,function(r,i){return o?o(r,i-1):(u=r,void(o=n?t(r,n):e(r)))});return a.columns=u,a}function i(r,e){function t(){if(f>=s)return u;if(o)return o=!1,i;var e,t=f;if(34===r.charCodeAt(t)){for(var n=t;n++<s;)if(34===r.charCodeAt(n)){if(34!==r.charCodeAt(n+1))break;++n}return f=n+2,e=r.charCodeAt(n+1),13===e?(o=!0,10===r.charCodeAt(n+2)&&++f):10===e&&(o=!0),r.slice(t+1,n).replace(/""/g,'"')}for(;f<s;){var a=1;if(e=r.charCodeAt(f++),10===e)o=!0;else if(13===e)o=!0,10===r.charCodeAt(f)&&(++f,++a);else if(e!==l)continue;return r.slice(t,f-a)}return r.slice(t)}for(var n,o,i={},u={},a=[],s=r.length,f=0,c=0;(n=t())!==u;){for(var p=[];n!==i&&n!==u;)p.push(n),n=t();e&&null==(p=e(p,c++))||a.push(p)}return a}function u(e,t){return null==t&&(t=n(e)),[t.map(f).join(r)].concat(e.map(function(e){return t.map(function(r){return f(e[r])}).join(r)})).join("\n")}function a(r){return r.map(s).join("\n")}function s(e){return e.map(f).join(r)}function f(r){return null==r?"":c.test(r+="")?'"'+r.replace(/\"/g,'""')+'"':r}var c=new RegExp('["'+r+"\n]"),l=r.charCodeAt(0);return{parse:o,parseRows:i,format:u,formatRows:a}}var i=o(","),u=i.parse,a=i.parseRows,s=i.format,f=i.formatRows,c=o("\t"),l=c.parse,p=c.parseRows,h=c.format,g=c.formatRows;r.dsvFormat=o,r.csvParse=u,r.csvParseRows=a,r.csvFormat=s,r.csvFormatRows=f,r.tsvParse=l,r.tsvParseRows=p,r.tsvFormat=h,r.tsvFormatRows=g,Object.defineProperty(r,"__esModule",{value:!0})})},{}],7:[function(r,e,t){function n(r,e){return a(r,e).val}function o(r){return i(r.lat,"lat")+" "+i(r.lon,"lon")}function i(r,e){var t=u(r,e);return t.whole+"° "+(t.minutes?t.minutes+"' ":"")+(t.seconds?t.seconds+'" ':"")+t.dir}function u(r,e){var t={lat:["N","S"],lon:["E","W"]}[e]||"",n=t[r>=0?0:1],o=Math.abs(r),i=Math.floor(o),u=o-i,a=60*u,s=Math.floor(a),f=Math.floor(60*(a-s));return{whole:i,minutes:s,seconds:f,dir:n}}function a(r,e,t){if(e||(e="NSEW"),"string"!=typeof r)return{val:null,regex:t};t=t||/[\s\,]*([\-|\—|\―]?[0-9.]+)°? *(?:([0-9.]+)['’′‘] *)?(?:([0-9.]+)(?:''|"|”|″) *)?([NSEW])?/gi;var n=t.exec(r);return n?n[4]&&e.indexOf(n[4])===-1?{val:null,regex:t}:{val:((n[1]?parseFloat(n[1]):0)+(n[2]?parseFloat(n[2])/60:0)+(n[3]?parseFloat(n[3])/3600:0))*(n[4]&&"S"===n[4]||"W"===n[4]?-1:1),regex:t,raw:n[0],dim:n[4]}:{val:null,regex:t}}function s(r,e){r=r.trim();var t=a(r,e);if(null===t.val)return null;var n=a(r,e,t.regex);return null===n.val?null:t.raw+n.raw!==r?null:t.dim?f(t.val,n.val,t.dim):[t.val,n.val]}function f(r,e,t){return"N"===t||"S"===t?[r,e]:"W"===t||"E"===t?[e,r]:void 0}e.exports=n,e.exports.pair=s,e.exports.format=i,e.exports.formatPair=o,e.exports.coordToDMS=u},{}],8:[function(r,e,t){"use strict";function n(r,e){r=Math.round(r*e),r<<=1,r<0&&(r=~r);for(var t="";r>=32;)t+=String.fromCharCode((32|31&r)+63),r>>=5;return t+=String.fromCharCode(r+63)}function o(r){for(var e=[],t=0;t<r.length;t++)e.push(r[t].slice().reverse());return e}var i={};i.decode=function(r,e){for(var t,n,o=0,i=0,u=0,a=[],s=0,f=0,c=null,l=Math.pow(10,e||5);o<r.length;){c=null,s=0,f=0;do c=r.charCodeAt(o++)-63,f|=(31&c)<<s,s+=5;while(c>=32);t=1&f?~(f>>1):f>>1,s=f=0;do c=r.charCodeAt(o++)-63,f|=(31&c)<<s,s+=5;while(c>=32);n=1&f?~(f>>1):f>>1,i+=t,u+=n,a.push([i/l,u/l])}return a},i.encode=function(r,e){if(!r.length)return"";for(var t=Math.pow(10,e||5),o=n(r[0][0],t)+n(r[0][1],t),i=1;i<r.length;i++){var u=r[i],a=r[i-1];o+=n(u[0]-a[0],t),o+=n(u[1]-a[1],t)}return o},i.fromGeoJSON=function(r,e){if(r&&"Feature"===r.type&&(r=r.geometry),!r||"LineString"!==r.type)throw new Error("Input must be a GeoJSON LineString");return i.encode(o(r.coordinates),e)},i.toGeoJSON=function(r,e){var t=i.decode(r,e);return{type:"LineString",coordinates:o(t)}},"object"==typeof e&&e.exports&&(e.exports=i)},{}],9:[function(r,e,t){(function(n){var o=function(){"use strict";function e(r){if(!r||!r.length)return 0;for(var e=0,t=0;e<r.length;e++)t=(t<<5)-t+r.charCodeAt(e)|0;return t}function o(r,e){return r.getElementsByTagName(e)}function i(r,e){return r.getAttribute(e)}function u(r,e){return parseFloat(i(r,e))}function a(r,e){var t=o(r,e);return t.length?t[0]:null}function s(r){return r.normalize&&r.normalize(),r}function f(r){for(var e=0,t=[];e<r.length;e++)t[e]=parseFloat(r[e]);return t}function c(r){var e={};for(var t in r)r[t]&&(e[t]=r[t]);return e}function l(r){return r&&s(r),r&&r.textContent||""}function p(r){return f(r.replace(y,"").split(","))}function h(r){for(var e=r.replace(x,"").split(w),t=[],n=0;n<e.length;n++)t.push(p(e[n]));return t}function g(r){var e,t=[u(r,"lon"),u(r,"lat")],n=a(r,"ele"),o=a(r,"gpxtpx:hr")||a(r,"hr"),i=a(r,"time");return n&&(e=parseFloat(l(n)),isNaN(e)||t.push(e)),{coordinates:t,time:i?l(i):null,heartRate:o?parseFloat(l(o)):null}}function d(){return{type:"FeatureCollection",features:[]}}function v(r){return void 0!==r.xml?r.xml:m.serializeToString(r)}var m,y=/\s*/g,x=/^\s*|\s*$/g,w=/\s+/;"undefined"!=typeof XMLSerializer?m=new XMLSerializer:"object"!=typeof t||"object"!=typeof n||n.browser||(m=new(r("xmldom").XMLSerializer));var L={kml:function(r){function t(r){var e,t;return r=r||"","#"===r.substr(0,1)&&(r=r.substr(1)),6!==r.length&&3!==r.length||(e=r),8===r.length&&(t=parseInt(r.substr(0,2),16)/255,e="#"+r.substr(2)),[e,isNaN(t)?void 0:t]}function n(r){return f(r.split(" "))}function u(r){var e=o(r,"coord","gx"),t=[],i=[];0===e.length&&(e=o(r,"gx:coord"));for(var u=0;u<e.length;u++)t.push(n(l(e[u])));for(var a=o(r,"when"),s=0;s<a.length;s++)i.push(l(a[s]));return{coords:t,times:i}}function s(r){var e,t,n,i,f,c=[],g=[];if(a(r,"MultiGeometry"))return s(a(r,"MultiGeometry"));if(a(r,"MultiTrack"))return s(a(r,"MultiTrack"));if(a(r,"gx:MultiTrack"))return s(a(r,"gx:MultiTrack"));for(n=0;n<y.length;n++)if(t=o(r,y[n]))for(i=0;i<t.length;i++)if(e=t[i],"Point"===y[n])c.push({type:"Point",coordinates:p(l(a(e,"coordinates")))});else if("LineString"===y[n])c.push({type:"LineString",coordinates:h(l(a(e,"coordinates")))});else if("Polygon"===y[n]){var d=o(e,"LinearRing"),v=[];for(f=0;f<d.length;f++)v.push(h(l(a(d[f],"coordinates"))));c.push({type:"Polygon",coordinates:v})}else if("Track"===y[n]||"gx:Track"===y[n]){var m=u(e);c.push({type:"LineString",coordinates:m.coords}
13977),m.times.length&&g.push(m.times)}return{geoms:c,coordTimes:g}}function c(r){var e,n=s(r),u={},f=l(a(r,"name")),c=l(a(r,"styleUrl")),p=l(a(r,"description")),h=a(r,"TimeSpan"),g=a(r,"ExtendedData"),d=a(r,"LineStyle"),v=a(r,"PolyStyle");if(!n.geoms.length)return[];if(f&&(u.name=f),"#"!==c[0]&&(c="#"+c),c&&m[c]&&(u.styleUrl=c,u.styleHash=m[c]),p&&(u.description=p),h){var y=l(a(h,"begin")),x=l(a(h,"end"));u.timespan={begin:y,end:x}}if(d){var w=t(l(a(d,"color"))),L=w[0],E=w[1],S=parseFloat(l(a(d,"width")));L&&(u.stroke=L),isNaN(E)||(u["stroke-opacity"]=E),isNaN(S)||(u["stroke-width"]=S)}if(v){var T=t(l(a(v,"color"))),M=T[0],P=T[1],N=l(a(v,"fill")),b=l(a(v,"outline"));M&&(u.fill=M),isNaN(P)||(u["fill-opacity"]=P),N&&(u["fill-opacity"]="1"===N?1:0),b&&(u["stroke-opacity"]="1"===b?1:0)}if(g){var F=o(g,"Data"),j=o(g,"SimpleData");for(e=0;e<F.length;e++)u[F[e].getAttribute("name")]=l(a(F[e],"value"));for(e=0;e<j.length;e++)u[j[e].getAttribute("name")]=l(j[e])}n.coordTimes.length&&(u.coordTimes=1===n.coordTimes.length?n.coordTimes[0]:n.coordTimes);var C={type:"Feature",geometry:1===n.geoms.length?n.geoms[0]:{type:"GeometryCollection",geometries:n.geoms},properties:u};return i(r,"id")&&(C.id=i(r,"id")),[C]}for(var g=d(),m={},y=["Polygon","LineString","Point","Track","gx:Track"],x=o(r,"Placemark"),w=o(r,"Style"),L=o(r,"StyleMap"),E=0;E<w.length;E++)m["#"+i(w[E],"id")]=e(v(w[E])).toString(16);for(var S=0;S<L.length;S++)m["#"+i(L[S],"id")]=e(v(L[S])).toString(16);for(var T=0;T<x.length;T++)g.features=g.features.concat(c(x[T]));return g},gpx:function(r){function e(r,e){var t=o(r,e),n=[],i=[],u=[],a=t.length;if(a<2)return{};for(var s=0;s<a;s++){var f=g(t[s]);n.push(f.coordinates),f.time&&i.push(f.time),f.heartRate&&u.push(f.heartRate)}return{line:n,times:i,heartRates:u}}function t(r){for(var t,n=o(r,"trkseg"),i=[],a=[],s=[],f=0;f<n.length;f++)t=e(n[f],"trkpt"),t.line&&i.push(t.line),t.times&&t.times.length&&a.push(t.times),t.heartRates&&t.heartRates.length&&s.push(t.heartRates);if(0!==i.length){var c=u(r);return a.length&&(c.coordTimes=1===i.length?a[0]:a),s.length&&(c.heartRates=1===i.length?s[0]:s),{type:"Feature",properties:c,geometry:{type:1===i.length?"LineString":"MultiLineString",coordinates:1===i.length?i[0]:i}}}}function n(r){var t=e(r,"rtept");if(t.line){var n={type:"Feature",properties:u(r),geometry:{type:"LineString",coordinates:t.line}};return n}}function i(r){var e=u(r);return e.sym=l(a(r,"sym")),{type:"Feature",properties:e,geometry:{type:"Point",coordinates:g(r).coordinates}}}function u(r){var e,t=["name","desc","author","copyright","link","time","keywords"],n={};for(e=0;e<t.length;e++)n[t[e]]=l(a(r,t[e]));return c(n)}var s,f,p=o(r,"trk"),h=o(r,"rte"),v=o(r,"wpt"),m=d();for(s=0;s<p.length;s++)f=t(p[s]),f&&m.features.push(f);for(s=0;s<h.length;s++)f=n(h[s]),f&&m.features.push(f);for(s=0;s<v.length;s++)m.features.push(i(v[s]));return m}};return L}();"undefined"!=typeof e&&(e.exports=o)}).call(this,r("_process"))},{_process:3,xmldom:2}],10:[function(e,t,n){!function(e,o){"object"==typeof n&&"undefined"!=typeof t?o(n):"function"==typeof r&&r.amd?r(["exports"],o):o(e.topojson=e.topojson||{})}(this,function(r){"use strict";function e(){}function t(r){if(!r)return e;var t,n,o=r.scale[0],i=r.scale[1],u=r.translate[0],a=r.translate[1];return function(r,e){e||(t=n=0),r[0]=(t+=r[0])*o+u,r[1]=(n+=r[1])*i+a}}function n(r){if(!r)return e;var t,n,o=r.scale[0],i=r.scale[1],u=r.translate[0],a=r.translate[1];return function(r,e){e||(t=n=0);var s=Math.round((r[0]-u)/o),f=Math.round((r[1]-a)/i);r[0]=s-t,r[1]=f-n,t=s,n=f}}function o(r,e){for(var t,n=r.length,o=n-e;o<--n;)t=r[o],r[o++]=r[n],r[n]=t}function i(r,e){for(var t=0,n=r.length;t<n;){var o=t+n>>>1;r[o]<e?t=o+1:n=o}return t}function u(r,e){return"GeometryCollection"===e.type?{type:"FeatureCollection",features:e.geometries.map(function(e){return a(r,e)})}:a(r,e)}function a(r,e){var t={type:"Feature",id:e.id,properties:e.properties||{},geometry:s(r,e)};return null==e.id&&delete t.id,t}function s(r,e){function n(r,e){e.length&&e.pop();for(var t,n=l[r<0?~r:r],i=0,u=n.length;i<u;++i)e.push(t=n[i].slice()),c(t,i);r<0&&o(e,u)}function i(r){return r=r.slice(),c(r,0),r}function u(r){for(var e=[],t=0,o=r.length;t<o;++t)n(r[t],e);return e.length<2&&e.push(e[0].slice()),e}function a(r){for(var e=u(r);e.length<4;)e.push(e[0].slice());return e}function s(r){return r.map(a)}function f(r){var e=r.type;return"GeometryCollection"===e?{type:e,geometries:r.geometries.map(f)}:e in p?{type:e,coordinates:p[e](r)}:null}var c=t(r.transform),l=r.arcs,p={Point:function(r){return i(r.coordinates)}
13977,MultiPoint:function(r){return r.coordinates.map(i)},LineString:function(r){return u(r.arcs)},MultiLineString:function(r){return r.arcs.map(u)},Polygon:function(r){return s(r.arcs)},MultiPolygon:function(r){return r.arcs.map(s)}};return f(e)}function f(r,e){function t(e){var t,n=r.arcs[e<0?~e:e],o=n[0];return r.transform?(t=[0,0],n.forEach(function(r){t[0]+=r[0],t[1]+=r[1]})):t=n[n.length-1],e<0?[t,o]:[o,t]}function n(r,e){for(var t in r){var n=r[t];delete e[n.start],delete n.start,delete n.end,n.forEach(function(r){o[r<0?~r:r]=1}),a.push(n)}}var o={},i={},u={},a=[],s=-1;return e.forEach(function(t,n){var o,i=r.arcs[t<0?~t:t];i.length<3&&!i[1][0]&&!i[1][1]&&(o=e[++s],e[s]=t,e[n]=o)}),e.forEach(function(r){var e,n,o=t(r),a=o[0],s=o[1];if(e=u[a])if(delete u[e.end],e.push(r),e.end=s,n=i[s]){delete i[n.start];var f=n===e?e:e.concat(n);i[f.start=e.start]=u[f.end=n.end]=f}else i[e.start]=u[e.end]=e;else if(e=i[s])if(delete i[e.start],e.unshift(r),e.start=a,n=u[a]){delete u[n.end];var c=n===e?e:n.concat(e);i[c.start=n.start]=u[c.end=e.end]=c}else i[e.start]=u[e.end]=e;else e=[r],i[e.start=a]=u[e.end=s]=e}),n(u,i),n(i,u),e.forEach(function(r){o[r<0?~r:r]||a.push([r])}),a}function c(r){return s(r,l.apply(this,arguments))}function l(r,e,t){function n(r){var e=r<0?~r:r;(c[e]||(c[e]=[])).push({i:r,g:s})}function o(r){r.forEach(n)}function i(r){r.forEach(o)}function u(r){"GeometryCollection"===r.type?r.geometries.forEach(u):r.type in l&&(s=r,l[r.type](r.arcs))}var a=[];if(arguments.length>1){var s,c=[],l={LineString:o,MultiLineString:i,Polygon:i,MultiPolygon:function(r){r.forEach(i)}};u(e),c.forEach(arguments.length<3?function(r){a.push(r[0].i)}:function(r){t(r[0].g,r[r.length-1].g)&&a.push(r[0].i)})}else for(var p=0,h=r.arcs.length;p<h;++p)a.push(p);return{type:"MultiLineString",arcs:f(r,a)}}function p(r){var e=r[0],t=r[1],n=r[2];return Math.abs((e[0]-n[0])*(t[1]-e[1])-(e[0]-t[0])*(n[1]-e[1]))}function h(r){for(var e,t=-1,n=r.length,o=r[n-1],i=0;++t<n;)e=o,o=r[t],i+=e[0]*o[1]-e[1]*o[0];return i/2}function g(r){return s(r,d.apply(this,arguments))}function d(r,e){function t(r){r.forEach(function(e){e.forEach(function(e){(o[e=e<0?~e:e]||(o[e]=[])).push(r)})}),i.push(r)}function n(e){return Math.abs(h(s(r,{type:"Polygon",arcs:[e]}).coordinates[0]))}var o={},i=[],u=[];return e.forEach(function(r){"Polygon"===r.type?t(r.arcs):"MultiPolygon"===r.type&&r.arcs.forEach(t)}),i.forEach(function(r){if(!r._){var e=[],t=[r];for(r._=1,u.push(e);r=t.pop();)e.push(r),r.forEach(function(r){r.forEach(function(r){o[r<0?~r:r].forEach(function(r){r._||(r._=1,t.push(r))})})})}}
13977),i.forEach(function(r){delete r._}),{type:"MultiPolygon",arcs:u.map(function(e){var t,i=[];if(e.forEach(function(r){r.forEach(function(r){r.forEach(function(r){o[r<0?~r:r].length<2&&i.push(r)})})}),i=f(r,i),(t=i.length)>1)for(var u,a,s=1,c=n(i[0]);s<t;++s)(u=n(i[s]))>c&&(a=i[0],i[0]=i[s],i[s]=a,c=u);return i})}}function v(r){function e(r,e){r.forEach(function(r){r<0&&(r=~r);var t=o[r];t?t.push(e):o[r]=[e]})}function t(r,t){r.forEach(function(r){e(r,t)})}function n(r,e){"GeometryCollection"===r.type?r.geometries.forEach(function(r){n(r,e)}):r.type in a&&a[r.type](r.arcs,e)}var o={},u=r.map(function(){return[]}),a={LineString:e,MultiLineString:t,Polygon:t,MultiPolygon:function(r,e){r.forEach(function(r){t(r,e)})}};r.forEach(n);for(var s in o)for(var f=o[s],c=f.length,l=0;l<c;++l)for(var p=l+1;p<c;++p){var h,g=f[l],d=f[p];(h=u[g])[s=i(h,d)]!==d&&h.splice(s,0,d),(h=u[d])[s=i(h,g)]!==g&&h.splice(s,0,g)}return u}function m(r,e){return r[1][2]-e[1][2]}function y(){function r(r,e){for(;e>0;){var t=(e+1>>1)-1,o=n[t];if(m(r,o)>=0)break;n[o._=e]=o,n[r._=e=t]=r}}function e(r,e){for(;;){var t=e+1<<1,i=t-1,u=e,a=n[u];if(i<o&&m(n[i],a)<0&&(a=n[u=i]),t<o&&m(n[t],a)<0&&(a=n[u=t]),u===e)break;n[a._=e]=a,n[r._=e=u]=r}}var t={},n=[],o=0;return t.push=function(e){return r(n[e._=o]=e,o++),o},t.pop=function(){if(!(o<=0)){var r,t=n[0];return--o>0&&(r=n[o],e(n[r._=0]=r,0)),t}},t.remove=function(t){var i,u=t._;if(n[u]===t)return u!==--o&&(i=n[o],(m(i,t)<0?r:e)(n[i._=u]=i,u)),u},t}function x(r,e){function o(r){a.remove(r),r[1][2]=e(r),a.push(r)}var i=t(r.transform),u=n(r.transform),a=y();return e||(e=p),r.arcs.forEach(function(r){var t,n,s,f,c=[],l=0;for(n=0,s=r.length;n<s;++n)f=r[n],i(r[n]=[f[0],f[1],1/0],n);for(n=1,s=r.length-1;n<s;++n)t=r.slice(n-1,n+2),t[1][2]=e(t),c.push(t),a.push(t);for(n=0,s=c.length;n<s;++n)t=c[n],t.previous=c[n-1],t.next=c[n+1];for(;t=a.pop();){var p=t.previous,h=t.next;t[1][2]<l?t[1][2]=l:l=t[1][2],p&&(p.next=h,p[2]=t[2],o(p)),h&&(h.previous=p,h[0]=t[0],o(h))}r.forEach(u)}),r}var w="1.6.26";r.version=w,r.mesh=c,r.meshArcs=l,r.merge=g,r.mergeArcs=d,r.feature=u,r.neighbors=v,r.presimplify=x})},{}],11:[function(r,e,t){function n(r){function e(r){var e=v.substring(y).match(r);return e?(y+=e[0].length,e[0]):null}function t(r){return r&&m.match(/\d+/)&&(r.crs={type:"name",properties:{name:"urn:ogc:def:crs:EPSG::"+m}}),r}function n(){e(/^\s*/)}function o(){n();for(var r,t=0,o=[],i=[o],a=o;r=e(/^(\()/)||e(/^(\))/)||e(/^(\,)/)||e(u);){if("("===r)i.push(a),a=[],i[i.length-1].push(a),t++;else if(")"===r){if(0===a.length)return null;if(a=i.pop(),!a)return null;if(t--,0===t)break}else if(","===r)a=[],i[i.length-1].push(a);else{if(r.split(/\s/g).some(isNaN))return null;Array.prototype.push.apply(a,r.split(/\s/g).map(parseFloat))}n()}return 0!==t?null:o}function i(){for(var r,t,o=[];t=e(u)||e(/^(\,)/);)","===t?(o.push(r),r=[]):t.split(/\s/g).some(isNaN)||(r||(r=[]),Array.prototype.push.apply(r,t.split(/\s/g).map(parseFloat))),n();return r?(o.push(r),o.length?o:null):null}function a(){if(!e(/^(point)/i))return null;if(n(),!e(/^(\()/))return null;var r=i();return r?(n(),e(/^(\))/)?{type:"Point",coordinates:r[0]}:null):null}function s(){if(!e(/^(multipoint)/i))return null;n();var r=v.substring(v.indexOf("(")+1,v.length-1).replace(/\(/g,"").replace(/\)/g,"");v="MULTIPOINT ("+r+")";var t=o();return t?(n(),{type:"MultiPoint",coordinates:t}):null}function f(){if(!e(/^(multilinestring)/i))return null;n();var r=o();return r?(n(),{type:"MultiLineString",coordinates:r}):null}function c(){if(!e(/^(linestring)/i))return null;if(n(),!e(/^(\()/))return null;var r=i();return r&&e(/^(\))/)?{type:"LineString",coordinates:r}:null}function l(){if(!e(/^(polygon)/i))return null;n();var r=o();return r?{type:"Polygon",coordinates:r}:null}function p(){if(!e(/^(multipolygon)/i))return null;n();var r=o();return r?{type:"MultiPolygon",coordinates:r}:null}function h(){var r,t=[];if(!e(/^(geometrycollection)/i))return null;if(n(),!e(/^(\()/))return null;for(;r=g();)t.push(r),n(),e(/^(\,)/),n();return e(/^(\))/)?{type:"GeometryCollection",geometries:t}:null}function g(){return a()||c()||l()||s()||f()||p()||h()}var d=r.split(";"),v=d.pop(),m=(d.shift()||"").split("=").pop(),y=0;return t(g())}function o(r){function e(r){return r.join(" ")}function t(r){return r.map(e).join(", ")}function n(r){return r.map(t).map(u).join(", ")}function i(r){return r.map(n).map(u).join(", ")}function u(r){return"("+r+")"}switch("Feature"===r.type&&(r=r.geometry),r.type){case"Point":return"POINT ("+e(r.coordinates)+")";case"LineString":return"LINESTRING ("+t(r.coordinates)+")";case"Polygon":return"POLYGON ("+n(r.coordinates)+")";case"MultiPoint":return"MULTIPOINT ("+t(r.coordinates)+")";case"MultiPolygon":return"MULTIPOLYGON ("+i(r.coordinates)+")";case"MultiLineString":return"MULTILINESTRING ("+n(r.coordinates)+")";case"GeometryCollection":return"GEOMETRYCOLLECTION ("+r.geometries.map(o).join(", ")+")";default:throw new Error("stringify requires a valid GeoJSON Feature or geometry object as input")}}
13977e.exports=n,e.exports.parse=n,e.exports.stringify=o;var i=/[-+]?([0-9]*\.[0-9]+|[0-9]+)([eE][-+]?[0-9]+)?/,u=new RegExp("^"+i.source+"(\\s"+i.source+"){1,}")},{}]},{},[1])(1)});
13978
13979!function(a,t){"function"==typeof define&&define.amd?define(["leaflet"],t):"object"==typeof modules&&module.exports?module.exports=t(require("leaflet")):t(L)}(0,function(u){"use strict";return u.TileLayer.Provider=u.TileLayer.extend({initialize:function(a,t){var o=u.TileLayer.Provider.providers,e=a.split("."),r=e[0],i=e[1];if(!o[r])throw"No such provider ("+r+")";var n={url:o[r].url,options:o[r].options};if(i&&"variants"in o[r]){if(!(i in o[r].variants))throw"No such variant of "+r+" ("+i+")";var s,p=o[r].variants[i];s="string"==typeof p?{variant:p}:p.options,n={url:p.url||n.url,options:u.Util.extend({},n.options,s)}}var l=function(a){return-1===a.indexOf("{attribution.")?a:a.replace(/\{attribution.(\w*)\}/,function(a,t){return l(o[t].options.attribution)})};n.options.attribution=l(n.options.attribution);var m=u.Util.extend({},n.options,t);u.TileLayer.prototype.initialize.call(this,n.url,m)}}),u.TileLayer.Provider.providers={OpenStreetMap:{url:"https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png",options:{maxZoom:19,attribution:'&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'},variants:{Mapnik:{},BlackAndWhite:{url:"http://{s}.tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png",options:{maxZoom:18}},DE:{url:"https://{s}.tile.openstreetmap.de/tiles/osmde/{z}/{x}/{y}.png",options:{maxZoom:18}},CH:{url:"https://tile.osm.ch/switzerland/{z}/{x}/{y}.png",options:{maxZoom:18,bounds:[[45,5],[48,11]]}},France:{url:"https://{s}.tile.openstreetmap.fr/osmfr/{z}/{x}/{y}.png",options:{maxZoom:20,attribution:"&copy; Openstreetmap France | {attribution.OpenStreetMap}"}},HOT:{url:"https://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png",options:{attribution:'{attribution.OpenStreetMap}, Tiles courtesy of <a href="http://hot.openstreetmap.org/" target="_blank">Humanitarian OpenStreetMap Team</a>'}},BZH:{url:"https://tile.openstreetmap.bzh/br/{z}/{x}/{y}.png",options:{attribution:'{attribution.OpenStreetMap}, Tiles courtesy of <a href="http://www.openstreetmap.bzh/" target="_blank">Breton OpenStreetMap Team</a>',bounds:[[46.2,-5.5],[50,.7]]}}}},OpenInfraMap:{url:"https://tiles-{s}.openinframap.org/{variant}/{z}/{x}/{y}.png",options:{maxZoom:18,attribution:'{attribution.OpenStreetMap}, <a href="http://www.openinframap.org/about.html">About OpenInfraMap</a>'},variants:{Power:"power",Telecom:"telecoms",Petroleum:"petroleum",Water:"water"}},OpenSeaMap:{url:"https://tiles.openseamap.org/seamark/{z}/{x}/{y}.png",options:{attribution:'Map data: &copy; <a href="http://www.openseamap.org">OpenSeaMap</a> contributors'}},OpenPtMap:{url:"http://openptmap.org/tiles/{z}/{x}/{y}.png",options:{maxZoom:17,attribution:'Map data: &copy; <a href="http://www.openptmap.org">OpenPtMap</a> contributors'}},OpenTopoMap:{url:"https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png",options:{maxZoom:17,attribution:'Map data: {attribution.OpenStreetMap}, <a href="http://viewfinderpanoramas.org">SRTM</a> | Map style: &copy; <a href="https://opentopomap.org">OpenTopoMap</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)'}},OpenRailwayMap:{url:"https://{s}.tiles.openrailwaymap.org/standard/{z}/{x}/{y}.png",options:{maxZoom:19,attribution:'Map data: {attribution.OpenStreetMap} | Map style: &copy; <a href="https://www.OpenRailwayMap.org">OpenRailwayMap</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)'}},OpenFireMap:{url:"http://openfiremap.org/hytiles/{z}/{x}/{y}.png",options:{maxZoom:19,attribution:'Map data: {attribution.OpenStreetMap} | Map style: &copy; <a href="http://www.openfiremap.org">OpenFireMap</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)'}},SafeCast:{url:"https://s3.amazonaws.com/te512.safecast.org/{z}/{x}/{y}.png",options:{maxZoom:16,attribution:'Map data: {attribution.OpenStreetMap} | Map style: &copy; <a href="https://blog.safecast.org/about/">SafeCast</a> (<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)'}},Thunderforest:{url:"https://{s}.tile.thunderforest.com/{variant}/{z}/{x}/{y}.png?apikey={apikey}",options:{attribution:'&copy; <a href="http://www.thunderforest.com/">Thunderforest</a>, {attribution.OpenStreetMap}',variant:"cycle",apikey:"<insert your api key here>",maxZoom:22},variants:{OpenCycleMap:"cycle",Transport:{options:{variant:"transport"}},TransportDark:{options:{variant:"transport-dark"}},SpinalMap:{options:{variant:"spinal-map"}},Landscape:"landscape",Outdoors:"outdoors",Pioneer:"pioneer"}},OpenMapSurfer:{url:"https://korona.geog.uni-heidelberg.de/tiles/{variant}/x={x}&y={y}&z={z}",options:{maxZoom:20,variant:"roads",attribution:'Imagery from <a href="http://giscience.uni-hd.de/">GIScience Research Group @ University of Heidelberg</a> &mdash; Map data {attribution.OpenStreetMap}'},variants:{Roads:"roads",AdminBounds:{options:{variant:"adminb",maxZoom:19}},Grayscale:{options:{variant:"roadsg",maxZoom:19}}}},Hydda:{url:"https://{s}.tile.openstreetmap.se/hydda/{variant}/{z}/{x}/{y}.png",options:{maxZoom:18,variant:"full",attribution:'Tiles courtesy of <a href="http://openstreetmap.se/" target="_blank">
13979OpenStreetMap Sweden</a> &mdash; Map data {attribution.OpenStreetMap}'},variants:{Full:"full",Base:"base",RoadsAndLabels:"roads_and_labels"}},MapBox:{url:"https://api.tiles.mapbox.com/v4/{id}/{z}/{x}/{y}{r}.png?access_token={accessToken}",options:{attribution:'Imagery from <a href="http://mapbox.com/about/maps/">MapBox</a> &mdash; Map data {attribution.OpenStreetMap}',subdomains:"abcd",id:"streets",accessToken:"<insert your access token here>"}},Stamen:{url:"https://stamen-tiles-{s}.a.ssl.fastly.net/{variant}/{z}/{x}/{y}{r}.{ext}",options:{attribution:'Map tiles by <a href="http://stamen.com">Stamen Design</a>, <a href="http://creativecommons.org/licenses/by/3.0">CC BY 3.0</a> &mdash; Map data {attribution.OpenStreetMap}',subdomains:"abcd",minZoom:0,maxZoom:20,variant:"toner",ext:"png"},variants:{Toner:"toner",TonerBackground:"toner-background",TonerHybrid:"toner-hybrid",TonerLines:"toner-lines",TonerLabels:"toner-labels",TonerLite:"toner-lite",Watercolor:{url:"https://stamen-tiles-{s}.a.ssl.fastly.net/{variant}/{z}/{x}/{y}.{ext}",options:{variant:"watercolor",minZoom:1,maxZoom:16}},Terrain:{options:{variant:"terrain",minZoom:0,maxZoom:18}},TerrainBackground:{options:{variant:"terrain-background",minZoom:0,maxZoom:18}},TopOSMRelief:{url:"https://stamen-tiles-{s}.a.ssl.fastly.net/{variant}/{z}/{x}/{y}.{ext}",options:{variant:"toposm-color-relief",ext:"jpg",bounds:[[22,-132],[51,-56]]}},TopOSMFeatures:{options:{variant:"toposm-features",bounds:[[22,-132],[51,-56]],opacity:.9}}}},Esri:{url:"https://server.arcgisonline.com/ArcGIS/rest/services/{variant}/MapServer/tile/{z}/{y}/{x}",options:{variant:"World_Street_Map",attribution:"Tiles &copy; Esri"},variants:{WorldStreetMap:{options:{attribution:"{attribution.Esri} &mdash; Source: Esri, DeLorme, NAVTEQ, USGS, Intermap, iPC, NRCAN, Esri Japan, METI, Esri China (Hong Kong), Esri (Thailand), TomTom, 2012"}},DeLorme:{options:{variant:"Specialty/DeLorme_World_Base_Map",minZoom:1,maxZoom:11,attribution:"{attribution.Esri} &mdash; Copyright: &copy;2012 DeLorme"}},WorldTopoMap:{options:{variant:"World_Topo_Map",attribution:"{attribution.Esri} &mdash; Esri, DeLorme, NAVTEQ, TomTom, Intermap, iPC, USGS, FAO, NPS, NRCAN, GeoBase, Kadaster NL, Ordnance Survey, Esri Japan, METI, Esri China (Hong Kong), and the GIS User Community"}},WorldImagery:{options:{variant:"World_Imagery",attribution:"{attribution.Esri} &mdash; Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community"}},WorldTerrain:{options:{variant:"World_Terrain_Base",maxZoom:13,attribution:"{attribution.Esri} &mdash; Source: USGS, Esri, TANA, DeLorme, and NPS"}},WorldShadedRelief:{options:{variant:"World_Shaded_Relief",maxZoom:13,attribution:"{attribution.Esri} &mdash; Source: Esri"}},WorldPhysical:{options:{variant:"World_Physical_Map",maxZoom:8,attribution:"{attribution.Esri} &mdash; Source: US National Park Service"}},OceanBasemap:{options:{variant:"Ocean_Basemap",maxZoom:13,attribution:"{attribution.Esri} &mdash; Sources: GEBCO, NOAA, CHS, OSU, UNH, CSUMB, National Geographic, DeLorme, NAVTEQ, and Esri"}},NatGeoWorldMap:{options:{variant:"NatGeo_World_Map",maxZoom:16,attribution:"{attribution.Esri} &mdash; National Geographic, Esri, DeLorme, NAVTEQ, UNEP-WCMC, USGS, NASA, ESA, METI, NRCAN, GEBCO, NOAA, iPC"}},WorldGrayCanvas:{options:{variant:"Canvas/World_Light_Gray_Base",maxZoom:16,attribution:"{attribution.Esri} &mdash; Esri, DeLorme, NAVTEQ"}}}},OpenWeatherMap:{url:"http://{s}.tile.openweathermap.org/map/{variant}/{z}/{x}/{y}.png?appid={apiKey}",options:{maxZoom:19,attribution:'Map data &copy; <a href="http://openweathermap.org">OpenWeatherMap</a>',apiKey:"<insert your api key here>",opacity:.5},variants:{Clouds:"clouds",CloudsClassic:"clouds_cls",Precipitation:"precipitation",PrecipitationClassic:"precipitation_cls",Rain:"rain",RainClassic:"rain_cls",Pressure:"pressure",PressureContour:"pressure_cntr",Wind:"wind",Temperature:"temp",Snow:"snow"}},HERE:{url:"https://{s}.{base}.maps.cit.api.here.com/maptile/2.1/{type}/{mapID}/{variant}/{z}/{x}/{y}/{size}/{format}?app_id={app_id}&app_code={app_code}&lg={language}",options:{attribution:'Map &copy; 1987-2014 <a href="http://developer.here.com">HERE</a>',subdomains:"1234",mapID:"newest",app_id:"<insert your app_id here>",app_code:"<insert your app_code here>",base:"base",variant:"normal.day",maxZoom:20,type:"maptile",language:"eng",format:"png8",size:"256"},variants:{normalDay:"normal.day",normalDayCustom:"normal.day.custom",normalDayGrey:"normal.day.grey",normalDayMobile:"normal.day.mobile",normalDayGreyMobile:"normal.day.grey.mobile",normalDayTransit:"normal.day.transit",normalDayTransitMobile:"normal.day.transit.mobile",normalNight:"normal.night",normalNightMobile:"normal.night.mobile",normalNightGrey:"normal.night.grey",normalNightGreyMobile:"normal.night.grey.mobile",basicMap:{options:{type:"basetile"}},mapLabels:{options:{type:"labeltile",format:"png"}},trafficFlow:{options:{base:"traffic",type:"flowtile"}},carnavDayGrey:"carnav.day.grey",hybridDay:{options:{base:"aerial",variant:"hybrid.day"}},hybridDayMobile:{options:{base:"aerial",variant:"hybrid.day.mobile"}},pedestrianDay:"pedestrian.day",pedestrianNight:"pedestrian.night",satelliteDay:{options:{base:"aerial",variant:"satellite.day"}},terrainDay:{options:{base:"aerial",variant:"terrain.day"}},terrainDayMobile:{options:{base:"aerial",variant:"terrain.day.mobile"}}}},FreeMapSK:{url:"http://t{s}.freemap.sk/T/{z}/{x}/{y}.jpeg",options:{minZoom:8,maxZoom:16,subdomains:"1234",bounds:[[47.204642,15.996093],[49.830896,22.576904]],attribution:'{attribution.OpenStreetMap}, vizualization CC-By-SA 2.0 <a href="http://freemap.sk">Freemap.sk</a>'}},MtbMap:{url:"http://tile.mtbmap.cz/mtbmap_tiles/{z}/{x}/{y}.png",options:{attribution:"{attribution.OpenStreetMap} &amp; USGS"}},CartoDB:{url:"https://cartodb-basemaps-{s}.global.ssl.fastly.net/{variant}/{z}/{x}/{y}{r}.png",options:{attribution:'{attribution.OpenStreetMap} &copy; <a href="http://cartodb.com/attributions">CartoDB</a>',subdomains:"abcd",maxZoom:19,variant:"light_all"},variants:{Positron:"light_all",PositronNoLabels:"light_nolabels",PositronOnlyLabels:"light_only_labels",DarkMatter:"dark_all",DarkMatterNoLabels:"dark_nolabels",DarkMatterOnlyLabels:"dark_only_labels",Voyager:"rastertiles/voyager",VoyagerNoLabels:"rastertiles/voyager_nolabels",VoyagerOnlyLabels:"rastertiles/voyager_only_labels",VoyagerLabelsUnder:"rastertiles/voyager_labels_under"}},HikeBike:{url:"http://{s}.tiles.wmflabs.org/{variant}/{z}/{x}/{y}.png",options:{maxZoom:19,attribution:"{attribution.OpenStreetMap}",variant:"hikebike"},variants:{HikeBike:{}
vendor: 3,114 bytes, line 13979
13979,HillShading:{options:{maxZoom:15,variant:"hillshading"}}}},BasemapAT:{url:"https://maps{s}.wien.gv.at/basemap/{variant}/normal/google3857/{z}/{y}/{x}.{format}",options:{maxZoom:19,attribution:'Datenquelle: <a href="https://www.basemap.at">basemap.at</a>',subdomains:["","1","2","3","4"],format:"png",bounds:[[46.35877,8.782379],[49.037872,17.189532]],variant:"geolandbasemap"},variants:{basemap:{options:{maxZoom:20,variant:"geolandbasemap"}},grau:"bmapgrau",overlay:"bmapoverlay",highdpi:{options:{variant:"bmaphidpi",format:"jpeg"}},orthofoto:{options:{maxZoom:20,variant:"bmaporthofoto30cm",format:"jpeg"}}}},nlmaps:{url:"https://geodata.nationaalgeoregister.nl/tiles/service/wmts/{variant}/EPSG:3857/{z}/{x}/{y}.png",options:{minZoom:6,maxZoom:19,bounds:[[50.5,3.25],[54,7.6]],attribution:'Kaartgegevens &copy; <a href="kadaster.nl">Kadaster</a>'},variants:{standaard:"brtachtergrondkaart",pastel:"brtachtergrondkaartpastel",grijs:"brtachtergrondkaartgrijs",luchtfoto:{url:"https://geodata.nationaalgeoregister.nl/luchtfoto/rgb/wmts/1.0.0/2016_ortho25/EPSG:3857/{z}/{x}/{y}.png"}}},NASAGIBS:{url:"https://map1.vis.earthdata.nasa.gov/wmts-webmerc/{variant}/default/{time}/{tilematrixset}{maxZoom}/{z}/{y}/{x}.{format}",options:{attribution:'Imagery provided by services from the Global Imagery Browse Services (GIBS), operated by the NASA/GSFC/Earth Science Data and Information System (<a href="https://earthdata.nasa.gov">ESDIS</a>) with funding provided by NASA/HQ.',bounds:[[-85.0511287776,-179.999999975],[85.0511287776,179.999999975]],minZoom:1,maxZoom:9,format:"jpg",time:"",tilematrixset:"GoogleMapsCompatible_Level"},variants:{ModisTerraTrueColorCR:"MODIS_Terra_CorrectedReflectance_TrueColor",ModisTerraBands367CR:"MODIS_Terra_CorrectedReflectance_Bands367",ViirsEarthAtNight2012:{options:{variant:"VIIRS_CityLights_2012",maxZoom:8}},ModisTerraLSTDay:{options:{variant:"MODIS_Terra_Land_Surface_Temp_Day",format:"png",maxZoom:7,opacity:.75}},ModisTerraSnowCover:{options:{variant:"MODIS_Terra_Snow_Cover",format:"png",maxZoom:8,opacity:.75}},ModisTerraAOD:{options:{variant:"MODIS_Terra_Aerosol",format:"png",maxZoom:6,opacity:.75}},ModisTerraChlorophyll:{options:{variant:"MODIS_Terra_Chlorophyll_A",format:"png",maxZoom:7,opacity:.75}}}},NLS:{url:"https://nls-{s}.tileserver.com/nls/{z}/{x}/{y}.jpg",options:{attribution:'<a href="http://geo.nls.uk/maps/">National Library of Scotland Historic Maps</a>',bounds:[[49.6,-12],[61.7,3]],minZoom:1,maxZoom:18,subdomains:"0123"}},JusticeMap:{url:"http://www.justicemap.org/tile/{size}/{variant}/{z}/{x}/{y}.png",options:{attribution:'<a href="http://www.justicemap.org/terms.php">Justice Map</a>',size:"county",bounds:[[14,-180],[72,-56]]},variants:{income:"income",americanIndian:"indian",asian:"asian",black:"black",hispanic:"hispanic",multi:"multi",nonWhite:"nonwhite",white:"white",plurality:"plural"}},Wikimedia:{url:"https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}{r}.png",options:{attribution:'<a href="https://wikimediafoundation.org/wiki/Maps_Terms_of_Use">Wikimedia</a>',minZoom:1,maxZoom:19}},GeoportailFrance:{url:"https://wxs.ign.fr/{apikey}
13979/geoportail/wmts?REQUEST=GetTile&SERVICE=WMTS&VERSION=1.0.0&STYLE={style}&TILEMATRIXSET=PM&FORMAT={format}&LAYER={variant}&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}",options:{attribution:'<a target="_blank" href="https://www.geoportail.gouv.fr/">Geoportail France</a>',bounds:[[-75,-180],[81,180]],minZoom:2,maxZoom:18,apikey:"choisirgeoportail",format:"image/jpeg",style:"normal",variant:"GEOGRAPHICALGRIDSYSTEMS.MAPS.SCAN-EXPRESS.STANDARD"},variants:{parcels:{options:{variant:"CADASTRALPARCELS.PARCELS",maxZoom:20,style:"bdparcellaire",format:"image/png"}},ignMaps:"GEOGRAPHICALGRIDSYSTEMS.MAPS",maps:"GEOGRAPHICALGRIDSYSTEMS.MAPS.SCAN-EXPRESS.STANDARD",orthos:{options:{maxZoom:19,variant:"ORTHOIMAGERY.ORTHOPHOTOS"}}}}},u.tileLayer.provider=function(a,t){return new u.TileLayer.Provider(a,t)},u});
13980!function(t){function o(e){var t={next:function(){var t=e.shift();return{done:void 0===t,value:t}}};return n&&(t[Symbol.iterator]=function(){return t}),t}function i(t){return encodeURIComponent(t).replace(/%20/g,"+")}function r(t){return decodeURIComponent(t).replace(/\+/g," ")}var s,e,n=function(){try{return!!Symbol.iterator}catch(t){return!1}}();"URLSearchParams"in t&&"a=1"===new URLSearchParams("?a=1").toString()||((e=(s=function(t){if(Object.defineProperty(this,"_entries",{writable:!0,value:{}}),"string"==typeof t)""!==t&&this._fromString(t);else if(t instanceof s){var n=this;t.forEach(function(t,e){n.append(e,t)})}else{if(null===t||"object"!=typeof t)throw new TypeError("Unsupported input's type for URLSearchParams");if("[object Array]"===Object.prototype.toString.call(t))for(var e=0;e<t.length;e++){var o=t[e];if("[object Array]"!==Object.prototype.toString.call(o)&&2===o.length)throw new TypeError("Expected [string, any] as entry at index "+e+" of URLSearchParams's input");this.append(o[0],o[1])}else for(var i in t)t.hasOwnProperty(i)&&this.append(i,t[i])}}).prototype).append=function(t,e){t in this._entries?this._entries[t].push(String(e)):this._entries[t]=[String(e)]},e.delete=function(t){delete this._entries[t]},e.get=function(t){return t in this._entries?this._entries[t][0]:null},e.getAll=function(t){return t in this._entries?this._entries[t].slice(0):[]},e.has=function(t){return t in this._entries},e.set=function(t,e){this._entries[t]=[String(e)]},e.forEach=function(t,e){var n;for(var o in this._entries)if(this._entries.hasOwnProperty(o)){n=this._entries[o];for(var i=0;i<n.length;i++)t.call(e,n[i],o,this)}},e.keys=function(){var n=[];return this.forEach(function(t,e){n.push(e)}),o(n)},e.values=function(){var e=[];return this.forEach(function(t){e.push(t)}),o(e)},e.entries=function(){var n=[];return this.forEach(function(t,e){n.push([e,t])}),o(n)},n&&(e[Symbol.iterator]=e.entries),e.toString=function(){var n=[];return this.forEach(function(t,e){n.push(i(e)+"="+i(t))}),n.join("&")},t.URLSearchParams=s);var a=URLSearchParams.prototype;"function"!=typeof a.sort&&(a.sort=function(){var n=this,o=[];this.forEach(function(t,e){o.push([e,t]),n._entries||n.delete(e)}),o.sort(function(t,e){return t[0]<e[0]?-1:t[0]>e[0]?1:0}),n._entries&&(n._entries={});for(var t=0;t<o.length;t++)this.append(o[t][0],o[t][1])}),"function"!=typeof a._fromString&&Object.defineProperty(a,"_fromString",{enumerable:!1,configurable:!1,writable:!1,value:function(t){if(this._entries)this._entries={};else{var n=this;this.searchParams.forEach(function(t,e){n.delete(e)})}for(var e,o=(t=t.replace(/^\?/,"")).split("&"),i=0;i<o.length;i++)e=o[i].split("="),this.append(r(e[0]),1<e.length?r(e[1]):"")}})}("undefined"!=typeof global?global:"undefined"!=typeof window?window:"undefined"!=typeof self?self:this),function(h){var e,n;function t(t,e){"string"!=typeof t&&(t=String(t));var n,o=document;if(e&&(void 0===h.location||e!==h.location.href)){(n=(o=document.implementation.createHTMLDocument("")).createElement("base")).href=e,o.head.appendChild(n);try{if(0!==n.href.indexOf(e))throw new Error(n.href)}catch(t){throw new Error("URL unable to set base "+e+" due to "+t)}}var i=o.createElement("a");if(i.href=t,n&&(o.body.appendChild(i),i.href=i.href),":"===i.protocol||!/:/.test(i.href))throw new TypeError("Invalid URL");Object.defineProperty(this,"_anchorElement",{value:i});
13980var r=new URLSearchParams(this.search),s=!0,a=!0,p=this;["append","delete","set"].forEach(function(t){var e=r[t];r[t]=function(){e.apply(r,arguments),s&&(a=!1,p.search=r.toString(),a=!0)}}),Object.defineProperty(this,"searchParams",{value:r,enumerable:!0});var u=void 0;Object.defineProperty(this,"_updateSearchParams",{enumerable:!1,configurable:!1,writable:!1,value:function(){this.search!==u&&(u=this.search,a&&(s=!1,this.searchParams._fromString(this.search),s=!0))}})}if(function(){try{var t=new URL("b","http://a");return t.pathname="c%20d","http://a/c%20d"===t.href&&t.searchParams}catch(t){return!1}}()||(e=h.URL,n=t.prototype,["hash","host","hostname","port","protocol"].forEach(function(t){!function(e){Object.defineProperty(n,e,{get:function(){return this._anchorElement[e]},set:function(t){this._anchorElement[e]=t},enumerable:!0})}(t)}),Object.defineProperty(n,"search",{get:function(){return this._anchorElement.search},set:function(t){this._anchorElement.search=t,this._updateSearchParams()},enumerable:!0}),Object.defineProperties(n,{toString:{get:function(){var t=this;return function(){return t.href}}},href:{get:function(){return this._anchorElement.href.replace(/\?$/,"")},set:function(t){this._anchorElement.href=t,this._updateSearchParams()},enumerable:!0},pathname:{get:function(){return this._anchorElement.pathname.replace(/(^\/?)/,"/")},set:function(t){this._anchorElement.pathname=t},enumerable:!0},origin:{get:function(){var t={"http:":80,"https:":443,"ftp:":21}[this._anchorElement.protocol],e=this._anchorElement.port!=t&&""!==this._anchorElement.port;return this._anchorElement.protocol+"//"+this._anchorElement.hostname+(e?":"+this._anchorElement.port:"")},enumerable:!0},password:{get:function(){return""},set:function(t){},enumerable:!0},username:{get:function(){return""},set:function(t){},enumerable:!0}}),t.createObjectURL=function(t){return e.createObjectURL.apply(e,arguments)},t.revokeObjectURL=function(t){return e.revokeObjectURL.apply(e,arguments)},h.URL=t),void 0!==h.location&&!("origin"in h.location)){function o(){return h.location.protocol+"//"+h.location.hostname+(h.location.port?":"+h.location.port:"")}try{Object.defineProperty(h.location,"origin",{get:o,enumerable:!0})}catch(t){setInterval(function(){h.location.origin=o()},100)}}}("undefined"!=typeof global?global:"undefined"!=typeof window?window:"undefined"!=typeof self?self:this),L.Contao=L.Evented.extend({statics:{ATTRIBUTION:' | <a href="https://netzmacht.de/contao-leaflet" title="Powered by Leaflet extension for Contao CMS developed by netzmacht David Molineus">netzmacht</a>'},maps:{},icons:{},initialize:function(){L.Icon.Default.imagePath="assets/leaflet/libs/leaflet/images/",this.setGeoJsonListeners(L.GeoJSON)},addMap:function(t,e){return this.maps[t]=e,this.fire("map:added",{id:t,map:e}),this},getMap:function(t){return void 0===this.maps[t]?null:this.maps[t]},addIcon:function(t,e){return this.icons[t]=e,this.fire("icon:added",{id:t,icon:e}),this},loadIcons:function(t){for(var e=0;e<t.length;e++){var n;n="extraMarkers.icon"===t[e].type?L.ExtraMarkers.icon(t[e].options):L[t[e].type](t[e].options),this.addIcon(t[e].id,n)}},getIcon:function(t){return void 0===this.icons[t]?null:this.icons[t]},load:function(t,e,n,o,i){var r=this.createRequestUrl(t,i);return this.loadFile(r,e,n,o,i)},loadUrl:function(t,e,n,o,i){t=this.applyFilterToUrl(t,i);var r=omnivore[e](t,n,o);return i&&(L.stamp(r),i.options.dynamicLoad&&"fit"==r.options.boundsMode&&(r.options.requestUrl=t,i.on("moveend",r.refreshData,r),i.on("layerremove",function(t){t.layer===r&&i.off("moveend",r.updateBounds,r)})),i.fire("dataloading",{layer:r}),r.on("ready",function(){i.calculateFeatureBounds(r),i.fire("dataload",{layer:r})}),r.on("error",function(){i.fire("dataload",{layer:r})})),r},loadFile:function(t,e,n,o,i){return this.loadUrl(t,e,n,o,i)},pointToLayer:function(t,e){var n="marker",o=null;if(t.properties&&(t.properties.bounds=!0,t.properties.type&&(n=t.properties.type),t.properties.arguments&&(o=L[n].apply(L[n],t.properties.arguments),L.Util.setOptions(o,t.properties.options))),null===o&&(o=L[n](e,t.properties.options)),t.properties){if(t.properties.radius&&o.setRadius(t.properties.radius),t.properties.icon){var i=this.getIcon(t.properties.icon);i&&o.setIcon(i)}this.bindPopupFromFeature(o,t)}return this.fire("point:added",{marker:o,feature:t,latlng:e,type:n}),o},onEachFeature:function(t,e){t.properties&&(L.Util.setOptions(e,t.properties.options),this.bindPopupFromFeature(e,t),this.fire("feature:added",{feature:t,layer:e}))},bindPopupFromFeature:function(t,e){e.properties&&(e.properties.popup?t.bindPopup(e.properties.popup,e.properties.popupOptions):e.properties.popupContent&&t.bindPopup(e.properties.popupContent,e.properties.popupOptions))},setGeoJsonListeners:function(t){t&&t.prototype&&(t.prototype.options={pointToLayer:this.pointToLayer.bind(this),onEachFeature:this.onEachFeature.bind(this)})},createRequestUrl:function(t,e){var n,o="leaflet",i=document.location.search.substr(1).split("&");if(t=encodeURIComponent(t),""==i)t=document.location.pathname+"?"+[o,t].join("=");else{for(var r,s=i.length;s--;)if((r=i[s].split("="))[0]==o){r[1]=t,i[s]=r.join("=");break}s<0&&(i[i.length]=[o,t].join("=")),t=document.location.pathname+"?"+i.join("&")}return e&&e.options.dynamicLoad&&(t+="&f=bbox&v=",t+=(n=e.getBounds()).getSouth()+","+n.getWest(),t+=","+n.getNorth()+","+n.getEast()),t},applyFilterToUrl:function(t,e){var n,o,i;return e&&e.options.dynamicLoad?(t=new URL(t),o=new URLSearchParams(t.search),n=(i=e.getBounds()).getSouth()+","+i.getWest(),n+=","+i.getNorth()+","+i.getEast(),o.set("filter","bbox"),o.set("values",n),t.search=o.toString(),t.toString()):t}}
13980),L.contao=new L.Contao,L.Control.Attribution.addInitHook(function(){this.options.prefix+=L.Contao.ATTRIBUTION}),L.Control.Attribution.include({setPrefix:function(t){return-1===t.indexOf(L.Contao.ATTRIBUTION)&&(t+=L.Contao.ATTRIBUTION),this.options.prefix=t,this._update(),this}}),L.GeoJSON.include({refreshData:function(t){var e=L.geoJson(),n=this;e.on("ready",function(){var t,e=n.getLayers();for(t=0;t<e.length;t++)n.removeLayer(e[t]);for(e=this.getLayers(),t=0;t<e.length;t++)this.removeLayer(e[t]),n.addLayer(e[t])}),omnivore.geojson(L.contao.applyFilterToUrl(this.options.requestUrl,t.target),null,e)}}),L.Map.include({_dynamicBounds:null,calculateFeatureBounds:function(t,e){if(t){if(!this.options.adjustBounds&&!e)return;this._scanForBounds(t)}else this.eachLayer(this._scanForBounds,this);this._dynamicBounds&&this.fitBounds(this._dynamicBounds,this.getBoundsOptions())},getBoundsOptions:function(){return options={},this.options.boundsPadding?options.padding=this.options.boundsPadding:(this.options.boundsPaddingTopLeft&&(options.paddingTopLeft=this.options.boundsPaddingTopLeft),this.options.boundsPaddingBottomRight&&(options.paddingBottomRight=this.options.boundsPaddingBottomRight)),options},_scanForBounds:function(t){var e;!t.feature||t.feature.properties&&t.feature.properties.ignoreForBounds?L.MarkerClusterGroup&&t instanceof L.MarkerClusterGroup&&t.options.boundsMode&&"extend"==t.options.boundsMode?(e=t.getBounds()).isValid()&&(this._dynamicBounds?this._dynamicBounds.extend(e):this._dynamicBounds=L.latLngBounds(e.getSouthWest
13980(),e.getNorthEast())):(!t.options||t.options&&t.options.boundsMode&&!t.options.ignoreForBounds)&&t.eachLayer&&t.eachLayer(this._scanForBounds,this):t.getBounds?(e=t.getBounds()).isValid()&&(this._dynamicBounds?this._dynamicBounds.extend(e):this._dynamicBounds=L.latLngBounds(e.getSouthWest(),e.getNorthEast())):t.getLatLng&&(e=t.getLatLng(),this._dynamicBounds?this._dynamicBounds.extend(e):this._dynamicBounds=L.latLngBounds(e,e))}}),L.LatLngBounds.prototype.toOverpassBBoxString=function(){var t=this._southWest,e=this._northEast;return[t.lat,t.lng,e.lat,e.lng].join(",")},L.OverPassLayer=L.FeatureGroup.extend({options:{minZoom:0,endpoint:"//overpass-api.de/api/",query:"(node(BBOX)[organic];node(BBOX)[second_hand];);out qt;",amenityIcons:{}},initialize:function(t){t.pointToLayer||(t.pointToLayer=this.pointToLayer),t.onEachFeature||(t.onEachFeature=this.onEachFeature),L.Util.setOptions(this,t),this.options.dynamicLoad=!!this.options.query.match(/BBOX/g),this._layer=L.geoJson(),this._layers={},this.addLayer(this._layer)},refreshData:function(){if(!(this._map.getZoom()<this.options.minZoom)){var t=this._map.getBounds().toOverpassBBoxString(),e=this.options.query.replace(/(BBOX)/g,t),n=this.options.endpoint+"interpreter?data=[out:json];"+e;this._map.fire("dataloading",{layer:this}),this.request(n,function(t,e){var n=JSON.parse(e.response),o=osmtogeojson(n),i=L.geoJson(o,{pointToLayer:this.options.pointToLayer.bind(this),onEachFeature:this.options.onEachFeature.bind(this)});if(this.addLayer(i),this.removeLayer(this._layer),this._layer=i,"extend"===this.options.boundsMode&&i.getBounds().isValid()){var r=this._map.getBounds();r=r.extend(i.getBounds()),this._map.fitBounds(r,this._map.getBoundsOptions())}this._map.fire("dataload",{layer:this})}.bind(this))}},onAdd:function(t){"fit"===this.options.boundsMode&&this.options.dynamicLoad&&t.on("moveend",this.refreshData,this),this.refreshData()},pointToLayer:function(t,e){var n=null,o=L.marker(e,t.properties.options);return t.properties&&(t.properties.radius&&o.setRadius(t.properties.radius),t.properties.icon?n=this._map.getIcon(t.properties.icon):t.properties.tags&&t.properties.tags.amenity&&this.options.amenityIcons[t.properties.tags.amenity]&&(n=L.contao.getIcon(this.options.amenityIcons[t.properties.tags.amenity])),n&&o.setIcon(n)),this.options.overpassPopup&&o.bindPopup(this.options.overpassPopup(t,o)),this._map.fire("point:added",{marker:o,feature:t,latlng:e,type:"marker"}),o},onEachFeature:function(t,e){t.properties&&(L.Util.setOptions(e,t.properties.options),this.options.overpassPopup&&e.bindPopup(this.options.overpassPopup(t,e)),this._map.fire("feature:added",{feature:t,layer:e}))},request:function(t,e,n){var o=!1;if(void 0===window.XMLHttpRequest)return e(Error("Browser not supported"));if(void 0===n){var i=t.match(/^\s*https?:\/\/[^\/]*/);n=i&&i[0]!==location.protocol+"//"+location.hostname+(location.port?":"+location.port:"")}var r=new window.XMLHttpRequest;if(n&&!("withCredentials"in r)){r=new window.XDomainRequest;var s=e;e=function(){if(o)s.apply(this,arguments);else{var t=this,e=arguments;setTimeout(function(){s.apply(t,e)},0)}}}function a(){void 0===r.status||function(t){return 200<=t&&t<300||304===t}(r.status)?e.call(r,null,r):e.call(r,r,null)}return"onload"in r?r.onload=a:r.onreadystatechange=function(){4===r.readyState&&a()},r.onerror=function(t){e.call(this,t||!0,null),e=function(){}},r.onprogress=function(){},r.ontimeout=function(t){e.call(this,t,null),e=function(){}},r.onabort=function(t){e.call(this,t,null),e=function(){}},r.open("GET",t,!0),r.send(null),o=!0,r}});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.