{"version":3,"file":"ig.publicmaps.application.min.js","sources":["ig.publicmaps.application.js"],"sourcesContent":["/*! jQuery v2.1.1 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */\n!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) {\r\n var c = [], d = c.slice, e = c.concat, f = c.push, g = c.indexOf, h = {}, i = h.toString, j = h.hasOwnProperty, k = {}, l = a.document, m = \"2.1.1\", 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 d.call(this) }, get: function (a) { return null != a ? 0 > a ? this[a + this.length] : this[a] : d.call(this) }, pushStack: function (a) { var b = n.merge(this.constructor(), a); return b.prevObject = this, b.context = this.context, b }, each: function (a, b) { return n.each(this, a, b) }, map: function (a) { return this.pushStack(n.map(this, function (b, c) { return a.call(b, c, b) })) }, slice: function () { return this.pushStack(d.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(null) }, push: f, 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 != (a = arguments[h])) for (b in a) c = g[b], d = a[b], g !== d && (j && d && (n.isPlainObject(d) || (e = n.isArray(d))) ? (e ? (e = !1, f = c && n.isArray(c) ? c : []) : f = c && n.isPlainObject(c) ? c : {}, g[b] = n.extend(j, f, d)) : void 0 !== d && (g[b] = d)); 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, isWindow: function (a) { return null != a && a === a.window }, isNumeric: function (a) { return !n.isArray(a) && a - parseFloat(a) >= 0 }, isPlainObject: function (a) { return \"object\" !== n.type(a) || a.nodeType || n.isWindow(a) ? !1 : a.constructor && !j.call(a.constructor.prototype, \"isPrototypeOf\") ? !1 : !0 }, isEmptyObject: function (a) { var b; for (b in a) return !1; return !0 }, type: function (a) { return null == a ? a + \"\" : \"object\" == typeof a || \"function\" == typeof a ? h[i.call(a)] || \"object\" : typeof a }, globalEval: function (a) { var b, c = eval; a = n.trim(a), a && (1 === a.indexOf(\"use strict\") ? (b = l.createElement(\"script\"), b.text = a, l.head.appendChild(b).parentNode.removeChild(b)) : c(a)) }, 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, c) { var d, e = 0, f = a.length, g = s(a); if (c) { if (g) { for (; f > e; e++) if (d = b.apply(a[e], c), d === !1) break } else for (e in a) if (d = b.apply(a[e], c), d === !1) break } else if (g) { for (; f > e; e++) if (d = b.call(a[e], e, a[e]), d === !1) break } else for (e in a) if (d = b.call(a[e], e, a[e]), 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) : f.call(c, a)), c }, inArray: function (a, b, c) { return null == b ? -1 : g.call(b, a, c) }, merge: function (a, b) { for (var c = +b.length, d = 0, e = a.length; c > d; 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, f = 0, g = a.length, h = s(a), i = []; if (h) for (; g > f; f++) d = b(a[f], f, c), null != d && i.push(d); else for (f in a) d = b(a[f], f, c), null != d && i.push(d); return e.apply([], i) }, guid: 1, proxy: function (a, b) { var c, e, f; return \"string\" == typeof b && (c = a[b], b = a, a = c), n.isFunction(a) ? (e = d.call(arguments, 2), f = function () { return a.apply(b || this, e.concat(d.call(arguments))) }, f.guid = a.guid = a.guid || n.guid++, f) : void 0 }, now: Date.now, support: k }), n.each(\"Boolean Number String Function Array Date RegExp Object Error\".split(\" \"), function (a, b) { h[\"[object \" + b + \"]\"] = b.toLowerCase() }); function s(a) { var b = a.length, c = n.type(a); return \"function\" === c || n.isWindow(a) ? !1 : 1 === a.nodeType && b ? !0 : \"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\" + -new Date, v = a.document, w = 0, x = 0, y = gb(), z = gb(), A = gb(), B = function (a, b) { return a === b && (l = !0), 0 }, C = \"undefined\", D = 1 << 31, E = {}.hasOwnProperty, F = [], G = F.pop, H = F.push, I = F.push, J = F.slice, K = F.indexOf || function (a) { for (var b = 0, c = this.length; c > b; b++) if (this[b] === a) return b; return -1 }, L = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\", M = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\", N = \"(?:\\\\\\\\.|[\\\\w-]|[^\\\\x00-\\\\xa0])+\", O = N.replace(\"w\", \"w#\"), P = \"\\\\[\" + M + \"*(\" + N + \")(?:\" + M + \"*([*^$|!~]?=)\" + M + \"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\" + O + \"))|)\" + M + \"*\\\\]\", Q = \":(\" + N + \")(?:\\\\((('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + P + \")*)|.*)\\\\)|)\", R = new RegExp(\"^\" + M + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + M + \"+$\", \"g\"), S = new RegExp(\"^\" + M + \"*,\" + M + \"*\"), T = new RegExp(\"^\" + M + \"*([>+~]|\" + M + \")\" + M + \"*\"), U = new RegExp(\"=\" + M + \"*([^\\\\]'\\\"]*?)\" + M + \"*\\\\]\", \"g\"), V = new RegExp(Q), W = new RegExp(\"^\" + O + \"$\"), X = { ID: new RegExp(\"^#(\" + N + \")\"), CLASS: new RegExp(\"^\\\\.(\" + N + \")\"), TAG: new RegExp(\"^(\" + N.replace(\"w\", \"w*\") + \")\"), ATTR: new RegExp(\"^\" + P), PSEUDO: new RegExp(\"^\" + Q), CHILD: new RegExp(\"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" + M + \"*(even|odd|(([+-]|)(\\\\d*)n|)\" + M + \"*(?:([+-]|)\" + M + \"*(\\\\d+)|))\" + M + \"*\\\\)|)\", \"i\"), bool: new RegExp(\"^(?:\" + L + \")$\", \"i\"), needsContext: new RegExp(\"^\" + M + \"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" + M + \"*((?:-\\\\d)?\\\\d*)\" + M + \"*\\\\)|)(?=[^-]|$)\", \"i\") }, Y = /^(?:input|select|textarea|button)$/i, Z = /^h\\d$/i, $ = /^[^{]+\\{\\s*\\[native \\w/, _ = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/, ab = /[+~]/, bb = /'|\\\\/g, cb = new RegExp(\"\\\\\\\\([\\\\da-f]{1,6}\" + M + \"?|(\" + M + \")|.)\", \"ig\"), db = 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) }; try { I.apply(F = J.call(v.childNodes), v.childNodes), F[v.childNodes.length].nodeType } catch (eb) { I = { apply: F.length ? function (a, b) { H.apply(a, J.call(b)) } : function (a, b) { var c = a.length, d = 0; while (a[c++] = b[d++]); a.length = c - 1 } } } function fb(a, b, d, e) { var f, h, j, k, l, o, r, s, w, x; if ((b ? b.ownerDocument || b : v) !== n && m(b), b = b || n, d = d || [], !a || \"string\" != typeof a) return d; if (1 !== (k = b.nodeType) && 9 !== k) return []; if (p && !e) { if (f = _.exec(a)) if (j = f[1]) { if (9 === k) { if (h = b.getElementById(j), !h || !h.parentNode) return d; if (h.id === j) return d.push(h), d } else if (b.ownerDocument && (h = b.ownerDocument.getElementById(j)) && t(b, h) && h.id === j) return d.push(h), d } else { if (f[2]) return I.apply(d, b.getElementsByTagName(a)), d; if ((j = f[3]) && c.getElementsByClassName && b.getElementsByClassName) return I.apply(d, b.getElementsByClassName(j)), d } if (c.qsa && (!q || !q.test(a))) { if (s = r = u, w = b, x = 9 === k && a, 1 === k && \"object\" !== b.nodeName.toLowerCase()) { o = g(a), (r = b.getAttribute(\"id\")) ? s = r.replace(bb, \"\\\\$&\") : b.setAttribute(\"id\", s), s = \"[id='\" + s + \"'] \", l = o.length; while (l--) o[l] = s + qb(o[l]); w = ab.test(a) && ob(b.parentNode) || b, x = o.join(\",\") } if (x) try { return I.apply(d, w.querySelectorAll(x)), d } catch (y) { } finally { r || b.removeAttribute(\"id\") } } } return i(a.replace(R, \"$1\"), b, d, e) } function gb() { var a = []; function b(c, e) { return a.push(c + \" \") > d.cacheLength && delete b[a.shift()], b[c + \" \"] = e } return b } function hb(a) { return a[u] = !0, a } function ib(a) { var b = n.createElement(\"div\"); try { return !!a(b) } catch (c) { return !1 } finally { b.parentNode && b.parentNode.removeChild(b), b = null } } function jb(a, b) { var c = a.split(\"|\"), e = a.length; while (e--) d.attrHandle[c[e]] = b } function kb(a, b) { var c = b && a, d = c && 1 === a.nodeType && 1 === b.nodeType && (~b.sourceIndex || D) - (~a.sourceIndex || D); if (d) return d; if (c) while (c = c.nextSibling) if (c === b) return -1; return a ? 1 : -1 } function lb(a) { return function (b) { var c = b.nodeName.toLowerCase(); return \"input\" === c && b.type === a } } function mb(a) { return function (b) { var c = b.nodeName.toLowerCase(); return (\"input\" === c || \"button\" === c) && b.type === a } } function nb(a) { return hb(function (b) { return b = +b, hb(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 ob(a) { return a && typeof a.getElementsByTagName !== C && a } c = fb.support = {}, f = fb.isXML = function (a) { var b = a && (a.ownerDocument || a).documentElement; return b ? \"HTML\" !== b.nodeName : !1 }, m = fb.setDocument = function (a) { var b, e = a ? a.ownerDocument || a : v, g = e.defaultView; return e !== n && 9 === e.nodeType && e.documentElement ? (n = e, o = e.documentElement, p = !f(e), g && g !== g.top && (g.addEventListener ? g.addEventListener(\"unload\", function () { m() }, !1) : g.attachEvent && g.attachEvent(\"onunload\", function () { m() })), c.attributes = ib(function (a) { return a.className = \"i\", !a.getAttribute(\"className\") }), c.getElementsByTagName = ib(function (a) { return a.appendChild(e.createComment(\"\")), !a.getElementsByTagName(\"*\").length }), c.getElementsByClassName = $.test(e.getElementsByClassName) && ib(function (a) { return a.innerHTML = \"
\", a.firstChild.className = \"i\", 2 === a.getElementsByClassName(\"i\").length }), c.getById = ib(function (a) { return o.appendChild(a).id = u, !e.getElementsByName || !e.getElementsByName(u).length }), c.getById ? (d.find.ID = function (a, b) { if (typeof b.getElementById !== C && p) { var c = b.getElementById(a); return c && c.parentNode ? [c] : [] } }, d.filter.ID = function (a) { var b = a.replace(cb, db); return function (a) { return a.getAttribute(\"id\") === b } }) : (delete d.find.ID, d.filter.ID = function (a) { var b = a.replace(cb, db); return function (a) { var c = typeof a.getAttributeNode !== C && a.getAttributeNode(\"id\"); return c && c.value === b } }), d.find.TAG = c.getElementsByTagName ? function (a, b) { return typeof b.getElementsByTagName !== C ? b.getElementsByTagName(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 typeof b.getElementsByClassName !== C && p ? b.getElementsByClassName(a) : void 0 }, r = [], q = [], (c.qsa = $.test(e.querySelectorAll)) && (ib(function (a) { a.innerHTML = \"\", a.querySelectorAll(\"[msallowclip^='']\").length && q.push(\"[*^$]=\" + M + \"*(?:''|\\\"\\\")\"), a.querySelectorAll(\"[selected]\").length || q.push(\"\\\\[\" + M + \"*(?:value|\" + L + \")\"), a.querySelectorAll(\":checked\").length || q.push(\":checked\") }), ib(function (a) { var b = e.createElement(\"input\"); b.setAttribute(\"type\", \"hidden\"), a.appendChild(b).setAttribute(\"name\", \"D\"), a.querySelectorAll(\"[name=d]\").length && q.push(\"name\" + M + \"*[*^$|!~]?=\"), a.querySelectorAll(\":enabled\").length || q.push(\":enabled\", \":disabled\"), a.querySelectorAll(\"*,:x\"), q.push(\",.*:\") })), (c.matchesSelector = $.test(s = o.matches || o.webkitMatchesSelector || o.mozMatchesSelector || o.oMatchesSelector || o.msMatchesSelector)) && ib(function (a) { c.disconnectedMatch = s.call(a, \"div\"), s.call(a, \"[s!='']:x\"), r.push(\"!=\", Q) }), q = q.length && new RegExp(q.join(\"|\")), r = r.length && new RegExp(r.join(\"|\")), b = $.test(o.compareDocumentPosition), t = b || $.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 === e || a.ownerDocument === v && t(v, a) ? -1 : b === e || b.ownerDocument === v && t(v, b) ? 1 : k ? K.call(k, a) - K.call(k, b) : 0 : 4 & d ? -1 : 1) } : function (a, b) { if (a === b) return l = !0, 0; var c, d = 0, f = a.parentNode, g = b.parentNode, h = [a], i = [b]; if (!f || !g) return a === e ? -1 : b === e ? 1 : f ? -1 : g ? 1 : k ? K.call(k, a) - K.call(k, b) : 0; if (f === g) return kb(a, b); c = a; while (c = c.parentNode) h.unshift(c); c = b; while (c = c.parentNode) i.unshift(c); while (h[d] === i[d]) d++; return d ? kb(h[d], i[d]) : h[d] === v ? -1 : i[d] === v ? 1 : 0 }, e) : n }, fb.matches = function (a, b) { return fb(a, null, null, b) }, fb.matchesSelector = function (a, b) { if ((a.ownerDocument || a) !== n && m(a), b = b.replace(U, \"='$1']\"), !(!c.matchesSelector || !p || 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 fb(b, n, null, [a]).length > 0 }, fb.contains = function (a, b) { return (a.ownerDocument || a) !== n && m(a), t(a, b) }, fb.attr = function (a, b) { (a.ownerDocument || a) !== n && m(a); var e = d.attrHandle[b.toLowerCase()], f = e && E.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 }, fb.error = function (a) { throw new Error(\"Syntax error, unrecognized expression: \" + a) }, fb.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 = fb.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 = fb.selectors = { cacheLength: 50, createPseudo: hb, match: X, 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(cb, db), a[3] = (a[3] || a[4] || a[5] || \"\").replace(cb, db), \"~=\" === 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] || fb.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] && fb.error(a[0]), a }, PSEUDO: function (a) { var b, c = !a[6] && a[2]; return X.CHILD.test(a[0]) ? null : (a[3] ? a[2] = a[4] || a[5] || \"\" : c && V.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(cb, db).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(\"(^|\" + M + \")\" + a + \"(\" + M + \"|$)\")) && y(a, function (a) { return b.test(\"string\" == typeof a.className && a.className || typeof a.getAttribute !== C && a.getAttribute(\"class\") || \"\") }) }, ATTR: function (a, b, c) { return function (d) { var e = fb.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 + \" \").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; if (q) { if (f) { while (p) { l = b; while (l = l[p]) if (h ? l.nodeName.toLowerCase() === r : 1 === l.nodeType) return !1; o = p = \"only\" === a && !o && \"nextSibling\" } return !0 } if (o = [g ? q.firstChild : q.lastChild], g && s) { k = q[u] || (q[u] = {}), j = k[a] || [], n = j[0] === w && j[1], m = j[0] === w && j[2], l = n && q.childNodes[n]; while (l = ++n && l && l[p] || (m = n = 0) || o.pop()) if (1 === l.nodeType && ++m && l === b) { k[a] = [w, n, m]; break } } else if (s && (j = (b[u] || (b[u] = {}))[a]) && j[0] === w) m = j[1]; else while (l = ++n && l && l[p] || (m = n = 0) || o.pop()) if ((h ? l.nodeName.toLowerCase() === r : 1 === l.nodeType) && ++m && (s && ((l[u] || (l[u] = {}))[a] = [w, m]), l === b)) break; return m -= e, m === d || m % d === 0 && m / d >= 0 } } }, PSEUDO: function (a, b) { var c, e = d.pseudos[a] || d.setFilters[a.toLowerCase()] || fb.error(\"unsupported pseudo: \" + a); return e[u] ? e(b) : e.length > 1 ? (c = [a, a, \"\", b], d.setFilters.hasOwnProperty(a.toLowerCase()) ? hb(function (a, c) { var d, f = e(a, b), g = f.length; while (g--) d = K.call(a, f[g]), a[d] = !(c[d] = f[g]) }) : function (a) { return e(a, 0, c) }) : e } }, pseudos: { not: hb(function (a) { var b = [], c = [], d = h(a.replace(R, \"$1\")); return d[u] ? hb(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), !c.pop() } }), has: hb(function (a) { return function (b) { return fb(a, b).length > 0 } }), contains: hb(function (a) { return function (b) { return (b.textContent || b.innerText || e(b)).indexOf(a) > -1 } }), lang: hb(function (a) { return W.test(a || \"\") || fb.error(\"unsupported lang: \" + a), a = a.replace(cb, db).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 Z.test(a.nodeName) }, input: function (a) { return Y.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: nb(function () { return [0] }), last: nb(function (a, b) { return [b - 1] }), eq: nb(function (a, b, c) { return [0 > c ? c + b : c] }), even: nb(function (a, b) { for (var c = 0; b > c; c += 2) a.push(c); return a }), odd: nb(function (a, b) { for (var c = 1; b > c; c += 2) a.push(c); return a }), lt: nb(function (a, b, c) { for (var d = 0 > c ? c + b : c; --d >= 0;) a.push(d); return a }), gt: nb(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] = lb(b); for (b in { submit: !0, reset: !0 }) d.pseudos[b] = mb(b); function pb() { } pb.prototype = d.filters = d.pseudos, d.setFilters = new pb, g = fb.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 = S.exec(h))) && (e && (h = h.slice(e[0].length) || h), i.push(f = [])), c = !1, (e = T.exec(h)) && (c = e.shift(), f.push({ value: c, type: e[0].replace(R, \" \") }), h = h.slice(c.length)); for (g in d.filter) !(e = X[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 ? fb.error(a) : z(a, i).slice(0) }; function qb(a) { for (var b = 0, c = a.length, d = \"\"; c > b; b++) d += a[b].value; return d } function rb(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 = [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 (i = b[u] || (b[u] = {}), (h = i[d]) && h[0] === w && h[1] === f) return j[2] = h[2]; if (i[d] = j, j[2] = a(b, c, g)) return !0 } } } function sb(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 tb(a, b, c) { for (var d = 0, e = b.length; e > d; d++) fb(a, b[d], c); return c } function ub(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 vb(a, b, c, d, e, f) { return d && !d[u] && (d = vb(d)), e && !e[u] && (e = vb(e, f)), hb(function (f, g, h, i) { var j, k, l, m = [], n = [], o = g.length, p = f || tb(b || \"*\", h.nodeType ? [h] : h, []), q = !a || !f && b ? p : ub(p, m, a, h, i), r = c ? e || (f ? a : o || d) ? [] : g : q; if (c && c(q, r, h, i), d) { j = ub(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 ? K.call(f, l) : m[k]) > -1 && (f[j] = !(g[j] = l)) } } else r = ub(r === g ? r.splice(o, r.length) : r), e ? e(null, g, r, i) : I.apply(g, r) }) } function wb(a) { for (var b, c, e, f = a.length, g = d.relative[a[0].type], h = g || d.relative[\" \"], i = g ? 1 : 0, k = rb(function (a) { return a === b }, h, !0), l = rb(function (a) { return K.call(b, a) > -1 }, h, !0), m = [function (a, c, d) { return !g && (d || c !== j) || ((b = c).nodeType ? k(a, c, d) : l(a, c, d)) }]; f > i; i++) if (c = d.relative[a[i].type]) m = [rb(sb(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 vb(i > 1 && sb(m), i > 1 && qb(a.slice(0, i - 1).concat({ value: \" \" === a[i - 2].type ? \"*\" : \"\" })).replace(R, \"$1\"), c, e > i && wb(a.slice(i, e)), f > e && wb(a = a.slice(e)), f > e && qb(a)) } m.push(c) } return sb(m) } function xb(a, b) { var c = b.length > 0, e = a.length > 0, f = function (f, g, h, i, k) { var l, m, o, p = 0, q = \"0\", r = f && [], s = [], t = j, u = f || e && d.find.TAG(\"*\", k), v = w += null == t ? 1 : Math.random() || .1, x = u.length; for (k && (j = g !== n && g) ; q !== x && null != (l = u[q]) ; q++) { if (e && l) { m = 0; while (o = a[m++]) if (o(l, g, h)) { i.push(l); break } k && (w = v) } c && ((l = !o && l) && p--, f && r.push(l)) } if (p += q, c && q !== p) { m = 0; while (o = b[m++]) o(r, s, g, h); if (f) { if (p > 0) while (q--) r[q] || s[q] || (s[q] = G.call(i)); s = ub(s) } I.apply(i, s), k && !f && s.length > 0 && p + b.length > 1 && fb.uniqueSort(i) } return k && (w = v, j = t), r }; return c ? hb(f) : f } return h = fb.compile = function (a, b) { var c, d = [], e = [], f = A[a + \" \"]; if (!f) { b || (b = g(a)), c = b.length; while (c--) f = wb(b[c]), f[u] ? d.push(f) : e.push(f); f = A(a, xb(e, d)), f.selector = a } return f }, i = fb.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(cb, db), b) || [])[0], !b) return e; n && (b = b.parentNode), a = a.slice(j.shift().value.length) } i = X.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(cb, db), ab.test(j[0].type) && ob(b.parentNode) || b))) { if (j.splice(i, 1), a = f.length && qb(j), !a) return I.apply(e, f), e; break } } } return (n || h(a, o))(f, b, !p, e, ab.test(a) && ob(b.parentNode) || b), e }, c.sortStable = u.split(\"\").sort(B).join(\"\") === u, c.detectDuplicates = !!l, m(), c.sortDetached = ib(function (a) { return 1 & a.compareDocumentPosition(n.createElement(\"div\")) }), ib(function (a) { return a.innerHTML = \"\", \"#\" === a.firstChild.getAttribute(\"href\") }) || jb(\"type|href|height|width\", function (a, b, c) { return c ? void 0 : a.getAttribute(b, \"type\" === b.toLowerCase() ? 1 : 2) }), c.attributes && ib(function (a) { return a.innerHTML = \"\", a.firstChild.setAttribute(\"value\", \"\"), \"\" === a.firstChild.getAttribute(\"value\") }) || jb(\"value\", function (a, b, c) { return c || \"input\" !== a.nodeName.toLowerCase() ? void 0 : a.defaultValue }), ib(function (a) { return null == a.getAttribute(\"disabled\") }) || jb(L, function (a, b, c) { var d; return c ? void 0 : a[b] === !0 ? b.toLowerCase() : (d = a.getAttributeNode(b)) && d.specified ? d.value : null }), fb }(a); n.find = t, n.expr = t.selectors, n.expr[\":\"] = n.expr.pseudos, n.unique = t.uniqueSort, n.text = t.getText, n.isXMLDoc = t.isXML, n.contains = t.contains; var u = n.expr.match.needsContext, v = /^<(\\w+)\\s*\\/?>(?:<\\/\\1>|)$/, w = /^.[^:#\\[\\.,]*$/; function x(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 (w.test(b)) return n.filter(b, a, c); b = n.filter(b, a) } return n.grep(a, function (a) { return g.call(b, a) >= 0 !== 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 = this.length, d = [], e = this; if (\"string\" != typeof a) return this.pushStack(n(a).filter(function () { for (b = 0; c > b; b++) if (n.contains(e[b], this)) return !0 })); for (b = 0; c > b; b++) n.find(a, e[b], d); return d = this.pushStack(c > 1 ? n.unique(d) : d), d.selector = this.selector ? this.selector + \" \" + a : a, d }, filter: function (a) { return this.pushStack(x(this, a || [], !1)) }, not: function (a) { return this.pushStack(x(this, a || [], !0)) }, is: function (a) { return !!x(this, \"string\" == typeof a && u.test(a) ? n(a) : a || [], !1).length } }); var y, z = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]*))$/, A = n.fn.init = function (a, b) { var c, d; if (!a) return this; if (\"string\" == typeof a) { if (c = \"<\" === a[0] && \">\" === a[a.length - 1] && a.length >= 3 ? [null, a, null] : z.exec(a), !c || !c[1] && b) return !b || b.jquery ? (b || y).find(a) : this.constructor(b).find(a); if (c[1]) { if (b = b instanceof n ? b[0] : b, n.merge(this, n.parseHTML(c[1], b && b.nodeType ? b.ownerDocument || b : l, !0)), v.test(c[1]) && n.isPlainObject(b)) for (c in b) n.isFunction(this[c]) ? this[c](b[c]) : this.attr(c, b[c]); return this } return d = l.getElementById(c[2]), d && d.parentNode && (this.length = 1, this[0] = d), this.context = l, this.selector = a, this } return a.nodeType ? (this.context = this[0] = a, this.length = 1, this) : n.isFunction(a) ? \"undefined\" != typeof y.ready ? y.ready(a) : a(n) : (void 0 !== a.selector && (this.selector = a.selector, this.context = a.context), n.makeArray(a, this)) }; A.prototype = n.fn, y = n(l); var B = /^(?:parents|prev(?:Until|All))/, C = { children: !0, contents: !0, next: !0, prev: !0 }; n.extend({ dir: 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 }, sibling: function (a, b) { for (var c = []; a; a = a.nextSibling) 1 === a.nodeType && a !== b && c.push(a); return c } }), n.fn.extend({ has: function (a) { var b = n(a, this), c = b.length; return this.filter(function () { for (var a = 0; c > a; a++) if (n.contains(this, b[a])) return !0 }) }, closest: function (a, b) { for (var c, d = 0, e = this.length, f = [], g = u.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.unique(f) : f) }, index: function (a) { return a ? \"string\" == typeof a ? g.call(n(a), this[0]) : g.call(this, a.jquery ? a[0] : a) : this[0] && this[0].parentNode ? this.first().prevAll().length : -1 }, add: function (a, b) { return this.pushStack(n.unique(n.merge(this.get(), n(a, b)))) }, addBack: function (a) { return this.add(null == a ? this.prevObject : this.prevObject.filter(a)) } }); function D(a, b) { while ((a = a[b]) && 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 n.dir(a, \"parentNode\") }, parentsUntil: function (a, b, c) { return n.dir(a, \"parentNode\", c) }, next: function (a) { return D(a, \"nextSibling\") }, prev: function (a) { return D(a, \"previousSibling\") }, nextAll: function (a) { return n.dir(a, \"nextSibling\") }, prevAll: function (a) { return n.dir(a, \"previousSibling\") }, nextUntil: function (a, b, c) { return n.dir(a, \"nextSibling\", c) }, prevUntil: function (a, b, c) { return n.dir(a, \"previousSibling\", c) }, siblings: function (a) { return n.sibling((a.parentNode || {}).firstChild, a) }, children: function (a) { return n.sibling(a.firstChild) }, contents: function (a) { return a.contentDocument || 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 && (C[a] || n.unique(e), B.test(a) && e.reverse()), this.pushStack(e) } }); var E = /\\S+/g, F = {}; function G(a) { var b = F[a] = {}; return n.each(a.match(E) || [], function (a, c) { b[c] = !0 }), b } n.Callbacks = function (a) { a = \"string\" == typeof a ? F[a] || G(a) : n.extend({}, a); var b, c, d, e, f, g, h = [], i = !a.once && [], j = function (l) { for (b = a.memory && l, c = !0, g = e || 0, e = 0, f = h.length, d = !0; h && f > g; g++) if (h[g].apply(l[0], l[1]) === !1 && a.stopOnFalse) { b = !1; break } d = !1, h && (i ? i.length && j(i.shift()) : b ? h = [] : k.disable()) }, k = { add: function () { if (h) { var c = h.length; !function g(b) { n.each(b, function (b, c) { var d = n.type(c); \"function\" === d ? a.unique && k.has(c) || h.push(c) : c && c.length && \"string\" !== d && g(c) }) }(arguments), d ? f = h.length : b && (e = c, j(b)) } return this }, remove: function () { return h && n.each(arguments, function (a, b) { var c; while ((c = n.inArray(b, h, c)) > -1) h.splice(c, 1), d && (f >= c && f--, g >= c && g--) }), this }, has: function (a) { return a ? n.inArray(a, h) > -1 : !(!h || !h.length) }, empty: function () { return h = [], f = 0, this }, disable: function () { return h = i = b = void 0, this }, disabled: function () { return !h }, lock: function () { return i = void 0, b || k.disable(), this }, locked: function () { return !i }, fireWith: function (a, b) { return !h || c && !i || (b = b || [], b = [a, b.slice ? b.slice() : b], d ? i.push(b) : j(b)), this }, fire: function () { return k.fireWith(this, arguments), this }, fired: function () { return !!c } }; return k }, 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().done(c.resolve).fail(c.reject).progress(c.notify) : 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 = d.call(arguments), e = c.length, f = 1 !== e || a && n.isFunction(a.promise) ? e : 0, g = 1 === f ? a : n.Deferred(), h = function (a, b, c) { return function (e) { b[a] = this, c[a] = arguments.length > 1 ? d.call(arguments) : e, c === i ? g.notifyWith(b, c) : --f || g.resolveWith(b, c) } }, i, j, k; if (e > 1) for (i = new Array(e), j = new Array(e), k = new Array(e) ; e > b; b++) c[b] && n.isFunction(c[b].promise) ? c[b].promise().done(h(b, k, c)).fail(g.reject).progress(h(b, j, i)) : --f; return f || g.resolveWith(k, c), g.promise() } }); var H; 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 || (H.resolveWith(l, [n]), n.fn.triggerHandler && (n(l).triggerHandler(\"ready\"), n(l).off(\"ready\")))) } }); function I() { l.removeEventListener(\"DOMContentLoaded\", I, !1), a.removeEventListener(\"load\", I, !1), n.ready() } n.ready.promise = function (b) { return H || (H = n.Deferred(), \"complete\" === l.readyState ? setTimeout(n.ready) : (l.addEventListener(\"DOMContentLoaded\", I, !1), a.addEventListener(\"load\", I, !1))), H.promise(b) }, n.ready.promise(); var J = n.access = 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) n.access(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 }; n.acceptData = function (a) { return 1 === a.nodeType || 9 === a.nodeType || !+a.nodeType }; function K() { Object.defineProperty(this.cache = {}, 0, { get: function () { return {} } }), this.expando = n.expando + Math.random() } K.uid = 1, K.accepts = n.acceptData, K.prototype = { key: function (a) { if (!K.accepts(a)) return 0; var b = {}, c = a[this.expando]; if (!c) { c = K.uid++; try { b[this.expando] = { value: c }, Object.defineProperties(a, b) } catch (d) { b[this.expando] = c, n.extend(a, b) } } return this.cache[c] || (this.cache[c] = {}), c }, set: function (a, b, c) { var d, e = this.key(a), f = this.cache[e]; if (\"string\" == typeof b) f[b] = c; else if (n.isEmptyObject(f)) n.extend(this.cache[e], b); else for (d in b) f[d] = b[d]; return f }, get: function (a, b) { var c = this.cache[this.key(a)]; return void 0 === b ? c : c[b] }, access: function (a, b, c) { var d; return void 0 === b || b && \"string\" == typeof b && void 0 === c ? (d = this.get(a, b), void 0 !== d ? d : this.get(a, n.camelCase(b))) : (this.set(a, b, c), void 0 !== c ? c : b) }, remove: function (a, b) { var c, d, e, f = this.key(a), g = this.cache[f]; if (void 0 === b) this.cache[f] = {}; else { n.isArray(b) ? d = b.concat(b.map(n.camelCase)) : (e = n.camelCase(b), b in g ? d = [b, e] : (d = e, d = d in g ? [d] : d.match(E) || [])), c = d.length; while (c--) delete g[d[c]] } }, hasData: function (a) { return !n.isEmptyObject(this.cache[a[this.expando]] || {}) }, discard: function (a) { a[this.expando] && delete this.cache[a[this.expando]] } }; var L = new K, M = new K, N = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/, O = /([A-Z])/g; function P(a, b, c) { var d; if (void 0 === c && 1 === a.nodeType) if (d = \"data-\" + b.replace(O, \"-$1\").toLowerCase(), 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) { } M.set(a, b, c) } else c = void 0; return c } n.extend({\r\n hasData: function (a) { return M.hasData(a) || L.hasData(a) }, data: function (a, b, c) { return M.access(a, b, c) }, removeData: function (a, b) {\r\n M.remove(a, b)\r\n }, _data: function (a, b, c) { return L.access(a, b, c) }, _removeData: function (a, b) { L.remove(a, b) }\r\n }), 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 = M.get(f), 1 === f.nodeType && !L.get(f, \"hasDataAttrs\"))) { 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]))); L.set(f, \"hasDataAttrs\", !0) } return e } return \"object\" == typeof a ? this.each(function () { M.set(this, a) }) : J(this, function (b) { var c, d = n.camelCase(a); if (f && void 0 === b) { if (c = M.get(f, a), void 0 !== c) return c; if (c = M.get(f, d), void 0 !== c) return c; if (c = P(f, d, void 0), void 0 !== c) return c } else this.each(function () { var c = M.get(this, d); M.set(this, d, b), -1 !== a.indexOf(\"-\") && void 0 !== c && M.set(this, a, b) }) }, null, b, arguments.length > 1, null, !0) }, removeData: function (a) { return this.each(function () { M.remove(this, a) }) } }), n.extend({ queue: function (a, b, c) { var d; return a ? (b = (b || \"fx\") + \"queue\", d = L.get(a, b), c && (!d || n.isArray(c) ? d = L.access(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 L.get(a, c) || L.access(a, c, { empty: n.Callbacks(\"once memory\").add(function () { L.remove(a, [b + \"queue\", 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 = L.get(f[g], a + \"queueHooks\"), c && c.empty && (d++, c.empty.add(h)); return h(), e.promise(b) } }); var Q = /[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/.source, R = [\"Top\", \"Right\", \"Bottom\", \"Left\"], S = function (a, b) { return a = b || a, \"none\" === n.css(a, \"display\") || !n.contains(a.ownerDocument, a) }, T = /^(?:checkbox|radio)$/i; !function () { var a = l.createDocumentFragment(), b = a.appendChild(l.createElement(\"div\")), c = l.createElement(\"input\"); c.setAttribute(\"type\", \"radio\"), c.setAttribute(\"checked\", \"checked\"), c.setAttribute(\"name\", \"t\"), b.appendChild(c), k.checkClone = b.cloneNode(!0).cloneNode(!0).lastChild.checked, b.innerHTML = \"\", k.noCloneChecked = !!b.cloneNode(!0).lastChild.defaultValue }(); var U = \"undefined\"; k.focusinBubbles = \"onfocusin\" in a; var V = /^key/, W = /^(?:mouse|pointer|contextmenu)|click/, X = /^(?:focusinfocus|focusoutblur)$/, Y = /^([^.]*)(?:\\.(.+)|)$/; function Z() { return !0 } function $() { return !1 } function _() { try { return l.activeElement } catch (a) { } } n.event = { global: {}, add: function (a, b, c, d, e) { var f, g, h, i, j, k, l, m, o, p, q, r = L.get(a); if (r) { c.handler && (f = c, c = f.handler, e = f.selector), c.guid || (c.guid = n.guid++), (i = r.events) || (i = r.events = {}), (g = r.handle) || (g = r.handle = function (b) { return typeof n !== U && n.event.triggered !== b.type ? n.event.dispatch.apply(a, arguments) : void 0 }), b = (b || \"\").match(E) || [\"\"], j = b.length; while (j--) h = Y.exec(b[j]) || [], o = q = h[1], p = (h[2] || \"\").split(\".\").sort(), o && (l = n.event.special[o] || {}, o = (e ? l.delegateType : l.bindType) || o, l = n.event.special[o] || {}, k = 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(\".\") }, f), (m = i[o]) || (m = i[o] = [], m.delegateCount = 0, l.setup && l.setup.call(a, d, p, g) !== !1 || a.addEventListener && a.addEventListener(o, g, !1)), l.add && (l.add.call(a, k), k.handler.guid || (k.handler.guid = c.guid)), e ? m.splice(m.delegateCount++, 0, k) : m.push(k), n.event.global[o] = !0) } }, remove: function (a, b, c, d, e) { var f, g, h, i, j, k, l, m, o, p, q, r = L.hasData(a) && L.get(a); if (r && (i = r.events)) { b = (b || \"\").match(E) || [\"\"], j = b.length; while (j--) if (h = Y.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 = i[o] || [], h = h[2] && new RegExp(\"(^|\\\\.)\" + p.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\"), g = f = m.length; while (f--) k = m[f], !e && q !== k.origType || c && c.guid !== k.guid || h && !h.test(k.namespace) || d && d !== k.selector && (\"**\" !== d || !k.selector) || (m.splice(f, 1), k.selector && m.delegateCount--, l.remove && l.remove.call(a, k)); g && !m.length && (l.teardown && l.teardown.call(a, p, r.handle) !== !1 || n.removeEvent(a, o, r.handle), delete i[o]) } else for (o in i) n.event.remove(a, o + b[j], c, d, !0); n.isEmptyObject(i) && (delete r.handle, L.remove(a, \"events\")) } }, trigger: function (b, c, d, e) { var f, g, h, i, k, m, o, p = [d || l], q = j.call(b, \"type\") ? b.type : b, r = j.call(b, \"namespace\") ? b.namespace.split(\".\") : []; if (g = h = d = d || l, 3 !== d.nodeType && 8 !== d.nodeType && !X.test(q + n.event.triggered) && (q.indexOf(\".\") >= 0 && (r = q.split(\".\"), q = r.shift(), r.sort()), k = q.indexOf(\":\") < 0 && \"on\" + q, b = b[n.expando] ? b : new n.Event(q, \"object\" == typeof b && b), b.isTrigger = e ? 2 : 3, b.namespace = r.join(\".\"), b.namespace_re = b.namespace ? new RegExp(\"(^|\\\\.)\" + r.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\") : null, b.result = void 0, b.target || (b.target = d), c = null == c ? [b] : n.makeArray(c, [b]), o = n.event.special[q] || {}, e || !o.trigger || o.trigger.apply(d, c) !== !1)) { if (!e && !o.noBubble && !n.isWindow(d)) { for (i = o.delegateType || q, X.test(i + q) || (g = g.parentNode) ; g; g = g.parentNode) p.push(g), h = g; h === (d.ownerDocument || l) && p.push(h.defaultView || h.parentWindow || a) } f = 0; while ((g = p[f++]) && !b.isPropagationStopped()) b.type = f > 1 ? i : o.bindType || q, m = (L.get(g, \"events\") || {})[b.type] && L.get(g, \"handle\"), m && m.apply(g, c), m = k && g[k], m && m.apply && n.acceptData(g) && (b.result = m.apply(g, c), b.result === !1 && b.preventDefault()); return b.type = q, e || b.isDefaultPrevented() || o._default && o._default.apply(p.pop(), c) !== !1 || !n.acceptData(d) || k && n.isFunction(d[q]) && !n.isWindow(d) && (h = d[k], h && (d[k] = null), n.event.triggered = q, d[q](), n.event.triggered = void 0, h && (d[k] = h)), b.result } }, dispatch: function (a) { a = n.event.fix(a); var b, c, e, f, g, h = [], i = d.call(arguments), j = (L.get(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.namespace_re || a.namespace_re.test(g.namespace)) && (a.handleObj = g, a.data = g.data, e = ((n.event.special[g.origType] || {}).handle || g.handler).apply(f.elem, i), void 0 !== e && (a.result = e) === !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 && (!a.button || \"click\" !== a.type)) for (; i !== this; i = i.parentNode || this) if (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) >= 0 : 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 }, props: \"altKey bubbles cancelable ctrlKey currentTarget 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 offsetX offsetY pageX pageY screenX screenY toElement\".split(\" \"), filter: function (a, b) { var c, d, e, f = b.button; return null == a.pageX && null != b.clientX && (c = a.target.ownerDocument || l, d = c.documentElement, e = c.body, a.pageX = b.clientX + (d && d.scrollLeft || e && e.scrollLeft || 0) - (d && d.clientLeft || e && e.clientLeft || 0), a.pageY = b.clientY + (d && d.scrollTop || e && e.scrollTop || 0) - (d && d.clientTop || e && e.clientTop || 0)), a.which || void 0 === f || (a.which = 1 & f ? 1 : 2 & f ? 3 : 4 & f ? 2 : 0), a } }, fix: function (a) { if (a[n.expando]) return a; var b, c, d, e = a.type, f = a, g = this.fixHooks[e]; g || (this.fixHooks[e] = g = W.test(e) ? this.mouseHooks : V.test(e) ? this.keyHooks : {}), d = g.props ? this.props.concat(g.props) : this.props, a = new n.Event(f), b = d.length; while (b--) c = d[b], a[c] = f[c]; return a.target || (a.target = l), 3 === a.target.nodeType && (a.target = a.target.parentNode), g.filter ? g.filter(a, f) : a }, special: { load: { noBubble: !0 }, focus: { trigger: function () { return this !== _() && this.focus ? (this.focus(), !1) : void 0 }, delegateType: \"focusin\" }, blur: { trigger: function () { return this === _() && this.blur ? (this.blur(), !1) : void 0 }, delegateType: \"focusout\" }, click: { trigger: function () { return \"checkbox\" === this.type && this.click && n.nodeName(this, \"input\") ? (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, d) { var e = n.extend(new n.Event, c, { type: a, isSimulated: !0, originalEvent: {} }); d ? n.event.trigger(e, null, b) : n.event.dispatch.call(b, e), e.isDefaultPrevented() && c.preventDefault() } }, n.removeEvent = function (a, b, c) { a.removeEventListener && a.removeEventListener(b, c, !1) }, 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 ? Z : $) : 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 = { isDefaultPrevented: $, isPropagationStopped: $, isImmediatePropagationStopped: $, preventDefault: function () { var a = this.originalEvent; this.isDefaultPrevented = Z, a && a.preventDefault && a.preventDefault() }, stopPropagation: function () { var a = this.originalEvent; this.isPropagationStopped = Z, a && a.stopPropagation && a.stopPropagation() }, stopImmediatePropagation: function () { var a = this.originalEvent; this.isImmediatePropagationStopped = Z, 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 } } }), k.focusinBubbles || n.each({ focus: \"focusin\", blur: \"focusout\" }, function (a, b) { var c = function (a) { n.event.simulate(b, a.target, n.event.fix(a), !0) }; n.event.special[b] = { setup: function () { var d = this.ownerDocument || this, e = L.access(d, b); e || d.addEventListener(a, c, !0), L.access(d, b, (e || 0) + 1) }, teardown: function () { var d = this.ownerDocument || this, e = L.access(d, b) - 1; e ? L.access(d, b, e) : (d.removeEventListener(a, c, !0), L.remove(d, b)) } } }), n.fn.extend({ on: function (a, b, c, d, e) { var f, g; if (\"object\" == typeof a) { \"string\" != typeof b && (c = c || b, b = void 0); for (g in a) this.on(g, b, c, a[g], e); return this } if (null == c && null == d ? (d = b, c = b = void 0) : null == d && (\"string\" == typeof b ? (d = c, c = void 0) : (d = c, c = b, b = void 0)), d === !1) d = $; else if (!d) return this; return 1 === e && (f = d, d = function (a) { return n().off(a), f.apply(this, arguments) }, d.guid = f.guid || (f.guid = n.guid++)), this.each(function () { n.event.add(this, a, d, c, b) }) }, one: function (a, b, c, d) { return this.on(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 = $), 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 ab = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:]+)[^>]*)\\/>/gi, bb = /<([\\w:]+)/, cb = /<|?\\w+;/, db = /<(?:script|style|link)/i, eb = /checked\\s*(?:[^=]|=\\s*.checked.)/i, fb = /^$|\\/(?:java|ecma)script/i, gb = /^true\\/(.*)/, hb = /^\\s*\\s*$/g, ib = { option: [1, \"\"], thead: [1, \"document.\r\n * The DOM creation and traversing methods exposed here all mimic the\r\n * W3C XML DOM methods. Create a new parser with the\r\n * constructor.\r\n *\r\n * Inherits from:\r\n * - \r\n */\r\nOpenLayers.Format.XML = OpenLayers.Class(OpenLayers.Format, {\r\n \r\n /**\r\n * Property: namespaces\r\n * {Object} Mapping of namespace aliases to namespace URIs. Properties\r\n * of this object should not be set individually. Read-only. All\r\n * XML subclasses should have their own namespaces object. Use\r\n * to add or set a namespace alias after construction.\r\n */\r\n namespaces: null,\r\n \r\n /**\r\n * Property: namespaceAlias\r\n * {Object} Mapping of namespace URI to namespace alias. This object\r\n * is read-only. Use to add or set a namespace alias.\r\n */\r\n namespaceAlias: null,\r\n \r\n /**\r\n * Property: defaultPrefix\r\n * {String} The default namespace alias for creating element nodes.\r\n */\r\n defaultPrefix: null,\r\n \r\n /**\r\n * Property: readers\r\n * Contains public functions, grouped by namespace prefix, that will\r\n * be applied when a namespaced node is found matching the function\r\n * name. The function will be applied in the scope of this parser\r\n * with two arguments: the node being read and a context object passed\r\n * from the parent.\r\n */\r\n readers: {},\r\n \r\n /**\r\n * Property: writers\r\n * As a compliment to the property, this structure contains public\r\n * writing functions grouped by namespace alias and named like the\r\n * node names they produce.\r\n */\r\n writers: {},\r\n\r\n /**\r\n * Property: xmldom\r\n * {XMLDom} If this browser uses ActiveX, this will be set to a XMLDOM\r\n * object. It is not intended to be a browser sniffing property.\r\n * Instead, the xmldom property is used instead of document\r\n * where namespaced node creation methods are not supported. In all\r\n * other browsers, this remains null.\r\n */\r\n xmldom: null,\r\n\r\n /**\r\n * Constructor: OpenLayers.Format.XML\r\n * Construct an XML parser. The parser is used to read and write XML.\r\n * Reading XML from a string returns a DOM element. Writing XML from\r\n * a DOM element returns a string.\r\n *\r\n * Parameters:\r\n * options - {Object} Optional object whose properties will be set on\r\n * the object.\r\n */\r\n initialize: function(options) {\r\n if (OpenLayers.Format.XML.supportActiveX) {\r\n this.xmldom = new ActiveXObject(\"Microsoft.XMLDOM\");\r\n }\r\n OpenLayers.Format.prototype.initialize.apply(this, [options]);\r\n // clone the namespace object and set all namespace aliases\r\n this.namespaces = OpenLayers.Util.extend({}, this.namespaces);\r\n this.namespaceAlias = {};\r\n for(var alias in this.namespaces) {\r\n this.namespaceAlias[this.namespaces[alias]] = alias;\r\n }\r\n },\r\n \r\n /**\r\n * APIMethod: destroy\r\n * Clean up.\r\n */\r\n destroy: function() {\r\n this.xmldom = null;\r\n OpenLayers.Format.prototype.destroy.apply(this, arguments);\r\n },\r\n \r\n /**\r\n * Method: setNamespace\r\n * Set a namespace alias and URI for the format.\r\n *\r\n * Parameters:\r\n * alias - {String} The namespace alias (prefix).\r\n * uri - {String} The namespace URI.\r\n */\r\n setNamespace: function(alias, uri) {\r\n this.namespaces[alias] = uri;\r\n this.namespaceAlias[uri] = alias;\r\n },\r\n\r\n /**\r\n * APIMethod: read\r\n * Deserialize a XML string and return a DOM node.\r\n *\r\n * Parameters:\r\n * text - {String} A XML string\r\n \r\n * Returns:\r\n * {DOMElement} A DOM node\r\n */\r\n read: function(text) {\r\n var index = text.indexOf('<');\r\n if(index > 0) {\r\n text = text.substring(index);\r\n }\r\n var node = OpenLayers.Util.Try(\r\n OpenLayers.Function.bind((\r\n function() {\r\n var xmldom;\r\n /**\r\n * Since we want to be able to call this method on the prototype\r\n * itself, this.xmldom may not exist even if in IE.\r\n */\r\n if (OpenLayers.Format.XML.supportActiveX && !this.xmldom) {\r\n xmldom = new ActiveXObject(\"Microsoft.XMLDOM\");\r\n } else {\r\n xmldom = this.xmldom;\r\n \r\n }\r\n xmldom.loadXML(text);\r\n return xmldom;\r\n }\r\n ), this),\r\n function() {\r\n return new DOMParser().parseFromString(text, 'text/xml');\r\n },\r\n function() {\r\n var req = new XMLHttpRequest();\r\n req.open(\"GET\", \"data:\" + \"text/xml\" +\r\n \";charset=utf-8,\" + encodeURIComponent(text), false);\r\n if(req.overrideMimeType) {\r\n req.overrideMimeType(\"text/xml\");\r\n }\r\n req.send(null);\r\n return req.responseXML;\r\n }\r\n );\r\n\r\n if(this.keepData) {\r\n this.data = node;\r\n }\r\n\r\n return node;\r\n },\r\n\r\n /**\r\n * APIMethod: write\r\n * Serialize a DOM node into a XML string.\r\n * \r\n * Parameters:\r\n * node - {DOMElement} A DOM node.\r\n *\r\n * Returns:\r\n * {String} The XML string representation of the input node.\r\n */\r\n write: function(node) {\r\n var data;\r\n if(this.xmldom) {\r\n data = node.xml;\r\n } else {\r\n var serializer = new XMLSerializer();\r\n if (node.nodeType == 1) {\r\n // Add nodes to a document before serializing. Everything else\r\n // is serialized as is. This may need more work. See #1218 .\r\n var doc = document.implementation.createDocument(\"\", \"\", null);\r\n if (doc.importNode) {\r\n node = doc.importNode(node, true);\r\n }\r\n doc.appendChild(node);\r\n data = serializer.serializeToString(doc);\r\n } else {\r\n data = serializer.serializeToString(node);\r\n }\r\n }\r\n return data;\r\n },\r\n\r\n /**\r\n * APIMethod: createElementNS\r\n * Create a new element with namespace. This node can be appended to\r\n * another node with the standard node.appendChild method. For\r\n * cross-browser support, this method must be used instead of\r\n * document.createElementNS.\r\n *\r\n * Parameters:\r\n * uri - {String} Namespace URI for the element.\r\n * name - {String} The qualified name of the element (prefix:localname).\r\n * \r\n * Returns:\r\n * {Element} A DOM element with namespace.\r\n */\r\n createElementNS: function(uri, name) {\r\n var element;\r\n if(this.xmldom) {\r\n if(typeof uri == \"string\") {\r\n element = this.xmldom.createNode(1, name, uri);\r\n } else {\r\n element = this.xmldom.createNode(1, name, \"\");\r\n }\r\n } else {\r\n element = document.createElementNS(uri, name);\r\n }\r\n return element;\r\n },\r\n\r\n /**\r\n * APIMethod: createDocumentFragment\r\n * Create a document fragment node that can be appended to another node\r\n * created by createElementNS. This will call \r\n * document.createDocumentFragment outside of IE. In IE, the ActiveX\r\n * object's createDocumentFragment method is used.\r\n *\r\n * Returns:\r\n * {Element} A document fragment.\r\n */\r\n createDocumentFragment: function() {\r\n var element;\r\n if (this.xmldom) {\r\n element = this.xmldom.createDocumentFragment();\r\n } else {\r\n element = document.createDocumentFragment();\r\n }\r\n return element;\r\n },\r\n\r\n /**\r\n * APIMethod: createTextNode\r\n * Create a text node. This node can be appended to another node with\r\n * the standard node.appendChild method. For cross-browser support,\r\n * this method must be used instead of document.createTextNode.\r\n * \r\n * Parameters:\r\n * text - {String} The text of the node.\r\n * \r\n * Returns: \r\n * {DOMElement} A DOM text node.\r\n */\r\n createTextNode: function(text) {\r\n var node;\r\n if (typeof text !== \"string\") {\r\n text = String(text);\r\n }\r\n if(this.xmldom) {\r\n node = this.xmldom.createTextNode(text);\r\n } else {\r\n node = document.createTextNode(text);\r\n }\r\n return node;\r\n },\r\n\r\n /**\r\n * APIMethod: getElementsByTagNameNS\r\n * Get a list of elements on a node given the namespace URI and local name.\r\n * To return all nodes in a given namespace, use '*' for the name\r\n * argument. To return all nodes of a given (local) name, regardless\r\n * of namespace, use '*' for the uri argument.\r\n * \r\n * Parameters:\r\n * node - {Element} Node on which to search for other nodes.\r\n * uri - {String} Namespace URI.\r\n * name - {String} Local name of the tag (without the prefix).\r\n * \r\n * Returns:\r\n * {NodeList} A node list or array of elements.\r\n */\r\n getElementsByTagNameNS: function(node, uri, name) {\r\n var elements = [];\r\n if(node.getElementsByTagNameNS) {\r\n elements = node.getElementsByTagNameNS(uri, name);\r\n } else {\r\n // brute force method\r\n var allNodes = node.getElementsByTagName(\"*\");\r\n var potentialNode, fullName;\r\n for(var i=0, len=allNodes.length; i method.\r\n * value - {String} Optional text to be appended as a text node.\r\n *\r\n * Returns:\r\n * {Element} An element node.\r\n */\r\n createElementNSPlus: function(name, options) {\r\n options = options || {};\r\n // order of prefix preference\r\n // 1. in the uri option\r\n // 2. in the prefix option\r\n // 3. in the qualified name\r\n // 4. from the defaultPrefix\r\n var uri = options.uri || this.namespaces[options.prefix];\r\n if(!uri) {\r\n var loc = name.indexOf(\":\");\r\n uri = this.namespaces[name.substring(0, loc)];\r\n }\r\n if(!uri) {\r\n uri = this.namespaces[this.defaultPrefix];\r\n }\r\n var node = this.createElementNS(uri, name);\r\n if(options.attributes) {\r\n this.setAttributes(node, options.attributes);\r\n }\r\n var value = options.value;\r\n if(value != null) {\r\n node.appendChild(this.createTextNode(value));\r\n }\r\n return node;\r\n },\r\n \r\n /**\r\n * Method: setAttributes\r\n * Set multiple attributes given key value pairs from an object.\r\n *\r\n * Parameters:\r\n * node - {Element} An element node.\r\n * obj - {Object || Array} An object whose properties represent attribute\r\n * names and values represent attribute values. If an attribute name\r\n * is a qualified name (\"prefix:local\"), the prefix will be looked up\r\n * in the parsers {namespaces} object. If the prefix is found,\r\n * setAttributeNS will be used instead of setAttribute.\r\n */\r\n setAttributes: function(node, obj) {\r\n var value, uri;\r\n for(var name in obj) {\r\n if(obj[name] != null && obj[name].toString) {\r\n value = obj[name].toString();\r\n // check for qualified attribute name (\"prefix:local\")\r\n uri = this.namespaces[name.substring(0, name.indexOf(\":\"))] || null;\r\n this.setAttributeNS(node, uri, name, value);\r\n }\r\n }\r\n },\r\n\r\n /**\r\n * Method: getFirstElementChild\r\n * Implementation of firstElementChild attribute that works on ie7 and ie8.\r\n *\r\n * Parameters:\r\n * node - {DOMElement} The parent node (required).\r\n *\r\n * Returns:\r\n * {DOMElement} The first child element.\r\n */\r\n getFirstElementChild: function(node) {\r\n if (node.firstElementChild) {\r\n return node.firstElementChild;\r\n }\r\n else {\r\n var child = node.firstChild;\r\n while (child.nodeType != 1 && (child = child.nextSibling)) {}\r\n return child;\r\n }\r\n },\r\n\r\n /**\r\n * Method: readNode\r\n * Shorthand for applying one of the named readers given the node\r\n * namespace and local name. Readers take two args (node, obj) and\r\n * generally extend or modify the second.\r\n *\r\n * Parameters:\r\n * node - {DOMElement} The node to be read (required).\r\n * obj - {Object} The object to be modified (optional).\r\n *\r\n * Returns:\r\n * {Object} The input object, modified (or a new one if none was provided).\r\n */\r\n readNode: function(node, obj) {\r\n if(!obj) {\r\n obj = {};\r\n }\r\n var group = this.readers[node.namespaceURI ? this.namespaceAlias[node.namespaceURI]: this.defaultPrefix];\r\n if(group) {\r\n var local = node.localName || node.nodeName.split(\":\").pop();\r\n var reader = group[local] || group[\"*\"];\r\n if(reader) {\r\n reader.apply(this, [node, obj]);\r\n }\r\n }\r\n return obj;\r\n },\r\n\r\n /**\r\n * Method: readChildNodes\r\n * Shorthand for applying the named readers to all children of a node.\r\n * For each child of type 1 (element), is called.\r\n *\r\n * Parameters:\r\n * node - {DOMElement} The node to be read (required).\r\n * obj - {Object} The object to be modified (optional).\r\n *\r\n * Returns:\r\n * {Object} The input object, modified.\r\n */\r\n readChildNodes: function(node, obj) {\r\n if(!obj) {\r\n obj = {};\r\n }\r\n var children = node.childNodes;\r\n var child;\r\n for(var i=0, len=children.length; i group. If a local name is used (e.g. \"Name\") then\r\n * the namespace of the parent is assumed. If a local name is used\r\n * and no parent is supplied, then the default namespace is assumed.\r\n * obj - {Object} Structure containing data for the writer.\r\n * parent - {DOMElement} Result will be appended to this node. If no parent\r\n * is supplied, the node will not be appended to anything.\r\n *\r\n * Returns:\r\n * {DOMElement} The child node.\r\n */\r\n writeNode: function(name, obj, parent) {\r\n var prefix, local;\r\n var split = name.indexOf(\":\");\r\n if(split > 0) {\r\n prefix = name.substring(0, split);\r\n local = name.substring(split + 1);\r\n } else {\r\n if(parent) {\r\n prefix = this.namespaceAlias[parent.namespaceURI];\r\n } else {\r\n prefix = this.defaultPrefix;\r\n }\r\n local = name;\r\n }\r\n var child = this.writers[prefix][local].apply(this, [obj]);\r\n if(parent) {\r\n parent.appendChild(child);\r\n }\r\n return child;\r\n },\r\n\r\n /**\r\n * APIMethod: getChildEl\r\n * Get the first child element. Optionally only return the first child\r\n * if it matches the given name and namespace URI.\r\n *\r\n * Parameters:\r\n * node - {DOMElement} The parent node.\r\n * name - {String} Optional node name (local) to search for.\r\n * uri - {String} Optional namespace URI to search for.\r\n *\r\n * Returns:\r\n * {DOMElement} The first child. Returns null if no element is found, if\r\n * something significant besides an element is found, or if the element\r\n * found does not match the optional name and uri.\r\n */\r\n getChildEl: function(node, name, uri) {\r\n return node && this.getThisOrNextEl(node.firstChild, name, uri);\r\n },\r\n \r\n /**\r\n * APIMethod: getNextEl\r\n * Get the next sibling element. Optionally get the first sibling only\r\n * if it matches the given local name and namespace URI.\r\n *\r\n * Parameters:\r\n * node - {DOMElement} The node.\r\n * name - {String} Optional local name of the sibling to search for.\r\n * uri - {String} Optional namespace URI of the sibling to search for.\r\n *\r\n * Returns:\r\n * {DOMElement} The next sibling element. Returns null if no element is\r\n * found, something significant besides an element is found, or the\r\n * found element does not match the optional name and uri.\r\n */\r\n getNextEl: function(node, name, uri) {\r\n return node && this.getThisOrNextEl(node.nextSibling, name, uri);\r\n },\r\n \r\n /**\r\n * Method: getThisOrNextEl\r\n * Return this node or the next element node. Optionally get the first\r\n * sibling with the given local name or namespace URI.\r\n *\r\n * Parameters:\r\n * node - {DOMElement} The node.\r\n * name - {String} Optional local name of the sibling to search for.\r\n * uri - {String} Optional namespace URI of the sibling to search for.\r\n *\r\n * Returns:\r\n * {DOMElement} The next sibling element. Returns null if no element is\r\n * found, something significant besides an element is found, or the\r\n * found element does not match the query.\r\n */\r\n getThisOrNextEl: function(node, name, uri) {\r\n outer: for(var sibling=node; sibling; sibling=sibling.nextSibling) {\r\n switch(sibling.nodeType) {\r\n case 1: // Element\r\n if((!name || name === (sibling.localName || sibling.nodeName.split(\":\").pop())) &&\r\n (!uri || uri === sibling.namespaceURI)) {\r\n // matches\r\n break outer;\r\n }\r\n sibling = null;\r\n break outer;\r\n case 3: // Text\r\n if(/^\\s*$/.test(sibling.nodeValue)) {\r\n break;\r\n }\r\n case 4: // CDATA\r\n case 6: // ENTITY_NODE\r\n case 12: // NOTATION_NODE\r\n case 10: // DOCUMENT_TYPE_NODE\r\n case 11: // DOCUMENT_FRAGMENT_NODE\r\n sibling = null;\r\n break outer;\r\n } // ignore comments and processing instructions\r\n }\r\n return sibling || null;\r\n },\r\n \r\n /**\r\n * APIMethod: lookupNamespaceURI\r\n * Takes a prefix and returns the namespace URI associated with it on the given\r\n * node if found (and null if not). Supplying null for the prefix will\r\n * return the default namespace.\r\n *\r\n * For browsers that support it, this calls the native lookupNamesapceURI\r\n * function. In other browsers, this is an implementation of\r\n * http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespaceURI.\r\n *\r\n * For browsers that don't support the attribute.ownerElement property, this\r\n * method cannot be called on attribute nodes.\r\n * \r\n * Parameters:\r\n * node - {DOMElement} The node from which to start looking.\r\n * prefix - {String} The prefix to lookup or null to lookup the default namespace.\r\n * \r\n * Returns:\r\n * {String} The namespace URI for the given prefix. Returns null if the prefix\r\n * cannot be found or the node is the wrong type.\r\n */\r\n lookupNamespaceURI: function(node, prefix) {\r\n var uri = null;\r\n if(node) {\r\n if(node.lookupNamespaceURI) {\r\n uri = node.lookupNamespaceURI(prefix);\r\n } else {\r\n outer: switch(node.nodeType) {\r\n case 1: // ELEMENT_NODE\r\n if(node.namespaceURI !== null && node.prefix === prefix) {\r\n uri = node.namespaceURI;\r\n break outer;\r\n }\r\n var len = node.attributes.length;\r\n if(len) {\r\n var attr;\r\n for(var i=0; i on the instance. On other browsers, this will\r\n * either return an existing or create a new shared document (see\r\n * ).\r\n *\r\n * Returns:\r\n * {XMLDocument}\r\n */\r\n getXMLDoc: function() {\r\n if (!OpenLayers.Format.XML.document && !this.xmldom) {\r\n if (document.implementation && document.implementation.createDocument) {\r\n OpenLayers.Format.XML.document =\r\n document.implementation.createDocument(\"\", \"\", null);\r\n } else if (!this.xmldom && OpenLayers.Format.XML.supportActiveX) {\r\n this.xmldom = new ActiveXObject(\"Microsoft.XMLDOM\");\r\n }\r\n }\r\n return OpenLayers.Format.XML.document || this.xmldom;\r\n },\r\n\r\n CLASS_NAME: \"OpenLayers.Format.XML\" \r\n\r\n}); \r\n\r\nOpenLayers.Format.XML.CONTENT_TYPE = {EMPTY: 0, SIMPLE: 1, COMPLEX: 2, MIXED: 3};\r\n\r\n/**\r\n * APIFunction: OpenLayers.Format.XML.lookupNamespaceURI\r\n * Takes a prefix and returns the namespace URI associated with it on the given\r\n * node if found (and null if not). Supplying null for the prefix will\r\n * return the default namespace.\r\n *\r\n * For browsers that support it, this calls the native lookupNamesapceURI\r\n * function. In other browsers, this is an implementation of\r\n * http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-lookupNamespaceURI.\r\n *\r\n * For browsers that don't support the attribute.ownerElement property, this\r\n * method cannot be called on attribute nodes.\r\n * \r\n * Parameters:\r\n * node - {DOMElement} The node from which to start looking.\r\n * prefix - {String} The prefix to lookup or null to lookup the default namespace.\r\n * \r\n * Returns:\r\n * {String} The namespace URI for the given prefix. Returns null if the prefix\r\n * cannot be found or the node is the wrong type.\r\n */\r\nOpenLayers.Format.XML.lookupNamespaceURI = OpenLayers.Function.bind(\r\n OpenLayers.Format.XML.prototype.lookupNamespaceURI,\r\n OpenLayers.Format.XML.prototype\r\n);\r\n\r\n/**\r\n * Property: OpenLayers.Format.XML.document\r\n * {XMLDocument} XML document to reuse for creating non-HTML compliant nodes,\r\n * like document.createCDATASection.\r\n */\r\nOpenLayers.Format.XML.document = null;\r\n\r\n/**\r\n * APIFunction: OpenLayers.Format.XML.supportActiveX\r\n * Returns a poolean flag to check if this browser uses ActiveX.\r\n */\r\nOpenLayers.Format.XML.supportActiveX = (function () {\r\n return (Object.getOwnPropertyDescriptor &&\r\n Object.getOwnPropertyDescriptor(window, \"ActiveXObject\")) ||\r\n (\"ActiveXObject\" in window);\r\n})();\r\n/* ======================================================================\r\n OpenLayers/BaseTypes/Date.js\r\n ====================================================================== */\r\n\r\n/* Copyright (c) 2006-2015 by OpenLayers Contributors (see authors.txt for\r\n * full list of contributors). Published under the 2-clause BSD license.\r\n * See license.txt in the OpenLayers distribution or repository for the\r\n * full text of the license. */\r\n\r\n/**\r\n * @requires OpenLayers/SingleFile.js\r\n */\r\n\r\n/**\r\n * Namespace: OpenLayers.Date\r\n * Contains implementations of Date.parse and date.toISOString that match the\r\n * ECMAScript 5 specification for parsing RFC 3339 dates.\r\n * http://tools.ietf.org/html/rfc3339\r\n */\r\nOpenLayers.Date = {\r\n\r\n /** \r\n * APIProperty: dateRegEx\r\n * The regex to be used for validating dates. You can provide your own\r\n * regex for instance for adding support for years before BC. Default\r\n * value is: /^(?:(\\d{4})(?:-(\\d{2})(?:-(\\d{2}))?)?)?(?:(?:T(\\d{1,2}):(\\d{2}):(\\d{2}(?:\\.\\d+)?)(Z|(?:[+-]\\d{1,2}(?::(\\d{2}))?)))|Z)?$/\r\n */\r\n dateRegEx: /^(?:(\\d{4})(?:-(\\d{2})(?:-(\\d{2}))?)?)?(?:(?:T(\\d{1,2}):(\\d{2}):(\\d{2}(?:\\.\\d+)?)(Z|(?:[+-]\\d{1,2}(?::(\\d{2}))?)))|Z)?$/,\r\n\r\n /**\r\n * APIMethod: toISOString\r\n * Generates a string representing a date. The format of the string follows\r\n * the profile of ISO 8601 for date and time on the Internet (see\r\n * http://tools.ietf.org/html/rfc3339). If the toISOString method is\r\n * available on the Date prototype, that is used. The toISOString\r\n * method for Date instances is defined in ECMA-262.\r\n *\r\n * Parameters:\r\n * date - {Date} A date object.\r\n *\r\n * Returns:\r\n * {String} A string representing the date (e.g.\r\n * \"2010-08-07T16:58:23.123Z\"). If the date does not have a valid time\r\n * (i.e. isNaN(date.getTime())) this method returns the string \"Invalid\r\n * Date\". The ECMA standard says the toISOString method should throw\r\n * RangeError in this case, but Firefox returns a string instead. For\r\n * best results, use isNaN(date.getTime()) to determine date validity\r\n * before generating date strings.\r\n */\r\n toISOString: (function() {\r\n if (\"toISOString\" in Date.prototype) {\r\n return function(date) {\r\n return date.toISOString();\r\n };\r\n } else {\r\n return function(date) {\r\n var str;\r\n if (isNaN(date.getTime())) {\r\n // ECMA-262 says throw RangeError, Firefox returns\r\n // \"Invalid Date\"\r\n str = \"Invalid Date\";\r\n } else {\r\n str =\r\n date.getUTCFullYear() + \"-\" +\r\n OpenLayers.Number.zeroPad(date.getUTCMonth() + 1, 2) + \"-\" +\r\n OpenLayers.Number.zeroPad(date.getUTCDate(), 2) + \"T\" +\r\n OpenLayers.Number.zeroPad(date.getUTCHours(), 2) + \":\" +\r\n OpenLayers.Number.zeroPad(date.getUTCMinutes(), 2) + \":\" +\r\n OpenLayers.Number.zeroPad(date.getUTCSeconds(), 2) + \".\" +\r\n OpenLayers.Number.zeroPad(date.getUTCMilliseconds(), 3) + \"Z\";\r\n }\r\n return str;\r\n };\r\n }\r\n\r\n })(),\r\n\r\n /**\r\n * APIMethod: parse\r\n * Generate a date object from a string. The format for the string follows\r\n * the profile of ISO 8601 for date and time on the Internet (see\r\n * http://tools.ietf.org/html/rfc3339). We don't call the native\r\n * Date.parse because of inconsistency between implmentations. In\r\n * Chrome, calling Date.parse with a string that doesn't contain any\r\n * indication of the timezone (e.g. \"2011\"), the date is interpreted\r\n * in local time. On Firefox, the assumption is UTC.\r\n *\r\n * Parameters:\r\n * str - {String} A string representing the date (e.g.\r\n * \"2010\", \"2010-08\", \"2010-08-07\", \"2010-08-07T16:58:23.123Z\",\r\n * \"2010-08-07T11:58:23.123-06\").\r\n *\r\n * Returns:\r\n * {Date} A date object. If the string could not be parsed, an invalid\r\n * date is returned (i.e. isNaN(date.getTime())).\r\n */\r\n parse: function(str) {\r\n var date;\r\n var match = str.match(this.dateRegEx);\r\n if (match && (match[1] || match[7])) { // must have at least year or time\r\n var year = parseInt(match[1], 10) || 0;\r\n var month = (parseInt(match[2], 10) - 1) || 0;\r\n var day = parseInt(match[3], 10) || 1;\r\n date = new Date(Date.UTC(year, month, day));\r\n // optional time\r\n var type = match[7];\r\n if (type) {\r\n var hours = parseInt(match[4], 10);\r\n var minutes = parseInt(match[5], 10);\r\n var secFrac = parseFloat(match[6]);\r\n var seconds = secFrac | 0;\r\n var milliseconds = Math.round(1000 * (secFrac - seconds));\r\n date.setUTCHours(hours, minutes, seconds, milliseconds);\r\n // check offset\r\n if (type !== \"Z\") {\r\n var hoursOffset = parseInt(type, 10);\r\n var minutesOffset = parseInt(match[8], 10) || 0;\r\n var offset = -1000 * (60 * (hoursOffset * 60) + minutesOffset * 60);\r\n date = new Date(date.getTime() + offset);\r\n }\r\n }\r\n } else {\r\n date = new Date(\"invalid\");\r\n }\r\n return date;\r\n }\r\n};\r\n/* ======================================================================\r\n OpenLayers/Feature.js\r\n ====================================================================== */\r\n\r\n/* Copyright (c) 2006-2015 by OpenLayers Contributors (see authors.txt for\r\n * full list of contributors). Published under the 2-clause BSD license.\r\n * See license.txt in the OpenLayers distribution or repository for the\r\n * full text of the license. */\r\n\r\n\r\n/**\r\n * @requires OpenLayers/BaseTypes/Class.js\r\n * @requires OpenLayers/Util.js\r\n */\r\n\r\n/**\r\n * Class: OpenLayers.Feature\r\n * Features are combinations of geography and attributes. The OpenLayers.Feature\r\n * class specifically combines a marker and a lonlat.\r\n */\r\nOpenLayers.Feature = OpenLayers.Class({\r\n\r\n /** \r\n * Property: layer \r\n * {} \r\n */\r\n layer: null,\r\n\r\n /** \r\n * Property: id \r\n * {String} \r\n */\r\n id: null,\r\n \r\n /** \r\n * Property: lonlat \r\n * {} \r\n */\r\n lonlat: null,\r\n\r\n /** \r\n * Property: data \r\n * {Object} \r\n */\r\n data: null,\r\n\r\n /** \r\n * Property: marker \r\n * {} \r\n */\r\n marker: null,\r\n\r\n /**\r\n * APIProperty: popupClass\r\n * {} The class which will be used to instantiate\r\n * a new Popup. Default is .\r\n */\r\n popupClass: null,\r\n\r\n /** \r\n * Property: popup \r\n * {} \r\n */\r\n popup: null,\r\n\r\n /** \r\n * Constructor: OpenLayers.Feature\r\n * Constructor for features.\r\n *\r\n * Parameters:\r\n * layer - {} \r\n * lonlat - {} \r\n * data - {Object} \r\n * \r\n * Returns:\r\n * {}\r\n */\r\n initialize: function(layer, lonlat, data) {\r\n this.layer = layer;\r\n this.lonlat = lonlat;\r\n this.data = (data != null) ? data : {};\r\n this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + \"_\"); \r\n },\r\n\r\n /** \r\n * Method: destroy\r\n * nullify references to prevent circular references and memory leaks\r\n */\r\n destroy: function() {\r\n\r\n //remove the popup from the map\r\n if ((this.layer != null) && (this.layer.map != null)) {\r\n if (this.popup != null) {\r\n this.layer.map.removePopup(this.popup);\r\n }\r\n }\r\n // remove the marker from the layer\r\n if (this.layer != null && this.marker != null) {\r\n this.layer.removeMarker(this.marker);\r\n }\r\n\r\n this.layer = null;\r\n this.id = null;\r\n this.lonlat = null;\r\n this.data = null;\r\n if (this.marker != null) {\r\n this.destroyMarker(this.marker);\r\n this.marker = null;\r\n }\r\n if (this.popup != null) {\r\n this.destroyPopup(this.popup);\r\n this.popup = null;\r\n }\r\n },\r\n \r\n /**\r\n * Method: onScreen\r\n * \r\n * Returns:\r\n * {Boolean} Whether or not the feature is currently visible on screen\r\n * (based on its 'lonlat' property)\r\n */\r\n onScreen:function() {\r\n \r\n var onScreen = false;\r\n if ((this.layer != null) && (this.layer.map != null)) {\r\n var screenBounds = this.layer.map.getExtent();\r\n onScreen = screenBounds.containsLonLat(this.lonlat);\r\n } \r\n return onScreen;\r\n },\r\n \r\n\r\n /**\r\n * Method: createMarker\r\n * Based on the data associated with the Feature, create and return a marker object.\r\n *\r\n * Returns: \r\n * {} A Marker Object created from the 'lonlat' and 'icon' properties\r\n * set in this.data. If no 'lonlat' is set, returns null. If no\r\n * 'icon' is set, OpenLayers.Marker() will load the default image.\r\n * \r\n * Note - this.marker is set to return value\r\n * \r\n */\r\n createMarker: function() {\r\n\r\n if (this.lonlat != null) {\r\n this.marker = new OpenLayers.Marker(this.lonlat, this.data.icon);\r\n }\r\n return this.marker;\r\n },\r\n\r\n /**\r\n * Method: destroyMarker\r\n * Destroys marker.\r\n * If user overrides the createMarker() function, s/he should be able\r\n * to also specify an alternative function for destroying it\r\n */\r\n destroyMarker: function() {\r\n this.marker.destroy(); \r\n },\r\n\r\n /**\r\n * Method: createPopup\r\n * Creates a popup object created from the 'lonlat', 'popupSize',\r\n * and 'popupContentHTML' properties set in this.data. It uses\r\n * this.marker.icon as default anchor. \r\n * \r\n * If no 'lonlat' is set, returns null. \r\n * If no this.marker has been created, no anchor is sent.\r\n *\r\n * Note - the returned popup object is 'owned' by the feature, so you\r\n * cannot use the popup's destroy method to discard the popup.\r\n * Instead, you must use the feature's destroyPopup\r\n * \r\n * Note - this.popup is set to return value\r\n * \r\n * Parameters: \r\n * closeBox - {Boolean} create popup with closebox or not\r\n * \r\n * Returns:\r\n * {} Returns the created popup, which is also set\r\n * as 'popup' property of this feature. Will be of whatever type\r\n * specified by this feature's 'popupClass' property, but must be\r\n * of type .\r\n * \r\n */\r\n createPopup: function(closeBox) {\r\n\r\n if (this.lonlat != null) {\r\n if (!this.popup) {\r\n var anchor = (this.marker) ? this.marker.icon : null;\r\n var popupClass = this.popupClass ? \r\n this.popupClass : OpenLayers.Popup.Anchored;\r\n this.popup = new popupClass(this.id + \"_popup\", \r\n this.lonlat,\r\n this.data.popupSize,\r\n this.data.popupContentHTML,\r\n anchor, \r\n closeBox); \r\n } \r\n if (this.data.overflow != null) {\r\n this.popup.contentDiv.style.overflow = this.data.overflow;\r\n } \r\n \r\n this.popup.feature = this;\r\n } \r\n return this.popup;\r\n },\r\n\r\n \r\n /**\r\n * Method: destroyPopup\r\n * Destroys the popup created via createPopup.\r\n *\r\n * As with the marker, if user overrides the createPopup() function, s/he \r\n * should also be able to override the destruction\r\n */\r\n destroyPopup: function() {\r\n if (this.popup) {\r\n this.popup.feature = null;\r\n this.popup.destroy();\r\n this.popup = null;\r\n } \r\n },\r\n\r\n CLASS_NAME: \"OpenLayers.Feature\"\r\n});\r\n/* ======================================================================\r\n OpenLayers/Feature/Vector.js\r\n ====================================================================== */\r\n\r\n/* Copyright (c) 2006-2015 by OpenLayers Contributors (see authors.txt for\r\n * full list of contributors). Published under the 2-clause BSD license.\r\n * See license.txt in the OpenLayers distribution or repository for the\r\n * full text of the license. */\r\n\r\n// TRASH THIS\r\nOpenLayers.State = {\r\n /** states */\r\n UNKNOWN: 'Unknown',\r\n INSERT: 'Insert',\r\n UPDATE: 'Update',\r\n DELETE: 'Delete'\r\n};\r\n\r\n/**\r\n * @requires OpenLayers/Feature.js\r\n * @requires OpenLayers/Util.js\r\n */\r\n\r\n/**\r\n * Class: OpenLayers.Feature.Vector\r\n * Vector features use the OpenLayers.Geometry classes as geometry description.\r\n * They have an 'attributes' property, which is the data object, and a 'style'\r\n * property, the default values of which are defined in the \r\n * objects.\r\n * \r\n * Inherits from:\r\n * - \r\n */\r\nOpenLayers.Feature.Vector = OpenLayers.Class(OpenLayers.Feature, {\r\n\r\n /** \r\n * Property: fid \r\n * {String} \r\n */\r\n fid: null,\r\n \r\n /** \r\n * APIProperty: geometry \r\n * {} \r\n */\r\n geometry: null,\r\n\r\n /** \r\n * APIProperty: attributes \r\n * {Object} This object holds arbitrary, serializable properties that\r\n * describe the feature.\r\n */\r\n attributes: null,\r\n\r\n /**\r\n * Property: bounds\r\n * {} The box bounding that feature's geometry, that\r\n * property can be set by an object when\r\n * deserializing the feature, so in most cases it represents an\r\n * information set by the server. \r\n */\r\n bounds: null,\r\n\r\n /** \r\n * Property: state \r\n * {String} \r\n */\r\n state: null,\r\n \r\n /** \r\n * APIProperty: style \r\n * {Object} \r\n */\r\n style: null,\r\n\r\n /**\r\n * APIProperty: url\r\n * {String} If this property is set it will be taken into account by\r\n * {} when updating or deleting the feature.\r\n */\r\n url: null,\r\n \r\n /**\r\n * Property: renderIntent\r\n * {String} rendering intent currently being used\r\n */\r\n renderIntent: \"default\",\r\n \r\n /**\r\n * APIProperty: modified\r\n * {Object} An object with the originals of the geometry and attributes of\r\n * the feature, if they were changed. Currently this property is only read\r\n * by , and written by\r\n * , which sets the geometry property.\r\n * Applications can set the originals of modified attributes in the\r\n * attributes property. Note that applications have to check if this\r\n * object and the attributes property is already created before using it.\r\n * After a change made with ModifyFeature, this object could look like\r\n *\r\n * (code)\r\n * {\r\n * geometry: >Object\r\n * }\r\n * (end)\r\n *\r\n * When an application has made changes to feature attributes, it could\r\n * have set the attributes to something like this:\r\n *\r\n * (code)\r\n * {\r\n * attributes: {\r\n * myAttribute: \"original\"\r\n * }\r\n * }\r\n * (end)\r\n *\r\n * Note that only checks for truthy values in\r\n * *modified.geometry* and the attribute names in *modified.attributes*,\r\n * but it is recommended to set the original values (and not just true) as\r\n * attribute value, so applications could use this information to undo\r\n * changes.\r\n */\r\n modified: null,\r\n\r\n /** \r\n * Constructor: OpenLayers.Feature.Vector\r\n * Create a vector feature. \r\n * \r\n * Parameters:\r\n * geometry - {} The geometry that this feature\r\n * represents.\r\n * attributes - {Object} An optional object that will be mapped to the\r\n * property. \r\n * style - {Object} An optional style object.\r\n */\r\n initialize: function(geometry, attributes, style) {\r\n OpenLayers.Feature.prototype.initialize.apply(this,\r\n [null, null, attributes]);\r\n this.lonlat = null;\r\n this.geometry = geometry ? geometry : null;\r\n this.state = null;\r\n this.attributes = {};\r\n if (attributes) {\r\n this.attributes = OpenLayers.Util.extend(this.attributes,\r\n attributes);\r\n }\r\n this.style = style ? style : null; \r\n },\r\n \r\n /** \r\n * Method: destroy\r\n * nullify references to prevent circular references and memory leaks\r\n */\r\n destroy: function() {\r\n if (this.layer) {\r\n this.layer.removeFeatures(this);\r\n this.layer = null;\r\n }\r\n \r\n this.geometry = null;\r\n this.modified = null;\r\n OpenLayers.Feature.prototype.destroy.apply(this, arguments);\r\n },\r\n \r\n /**\r\n * Method: clone\r\n * Create a clone of this vector feature. Does not set any non-standard\r\n * properties.\r\n *\r\n * Returns:\r\n * {} An exact clone of this vector feature.\r\n */\r\n clone: function () {\r\n return new OpenLayers.Feature.Vector(\r\n this.geometry ? this.geometry.clone() : null,\r\n this.attributes,\r\n this.style);\r\n },\r\n\r\n /**\r\n * Method: onScreen\r\n * Determine whether the feature is within the map viewport. This method\r\n * tests for an intersection between the geometry and the viewport\r\n * bounds. If a more efficient but less precise geometry bounds\r\n * intersection is desired, call the method with the boundsOnly\r\n * parameter true.\r\n *\r\n * Parameters:\r\n * boundsOnly - {Boolean} Only test whether a feature's bounds intersects\r\n * the viewport bounds. Default is false. If false, the feature's\r\n * geometry must intersect the viewport for onScreen to return true.\r\n * \r\n * Returns:\r\n * {Boolean} The feature is currently visible on screen (optionally\r\n * based on its bounds if boundsOnly is true).\r\n */\r\n onScreen:function(boundsOnly) {\r\n var onScreen = false;\r\n if(this.layer && this.layer.map) {\r\n var screenBounds = this.layer.map.getExtent();\r\n if(boundsOnly) {\r\n var featureBounds = this.geometry.getBounds();\r\n onScreen = screenBounds.intersectsBounds(featureBounds);\r\n } else {\r\n var screenPoly = screenBounds.toGeometry();\r\n onScreen = screenPoly.intersects(this.geometry);\r\n }\r\n } \r\n return onScreen;\r\n },\r\n\r\n /**\r\n * Method: getVisibility\r\n * Determine whether the feature is displayed or not. It may not displayed\r\n * because:\r\n * - its style display property is set to 'none',\r\n * - it doesn't belong to any layer,\r\n * - the styleMap creates a symbolizer with display property set to 'none'\r\n * for it,\r\n * - the layer which it belongs to is not visible.\r\n * \r\n * Returns:\r\n * {Boolean} The feature is currently displayed.\r\n */\r\n getVisibility: function() {\r\n return !(this.style && this.style.display == 'none' ||\r\n !this.layer ||\r\n this.layer && this.layer.styleMap &&\r\n this.layer.styleMap.createSymbolizer(this, this.renderIntent).display == 'none' ||\r\n this.layer && !this.layer.getVisibility());\r\n },\r\n \r\n /**\r\n * Method: createMarker\r\n * HACK - we need to decide if all vector features should be able to\r\n * create markers\r\n * \r\n * Returns:\r\n * {} For now just returns null\r\n */\r\n createMarker: function() {\r\n return null;\r\n },\r\n\r\n /**\r\n * Method: destroyMarker\r\n * HACK - we need to decide if all vector features should be able to\r\n * delete markers\r\n * \r\n * If user overrides the createMarker() function, s/he should be able\r\n * to also specify an alternative function for destroying it\r\n */\r\n destroyMarker: function() {\r\n // pass\r\n },\r\n\r\n /**\r\n * Method: createPopup\r\n * HACK - we need to decide if all vector features should be able to\r\n * create popups\r\n * \r\n * Returns:\r\n * {} For now just returns null\r\n */\r\n createPopup: function() {\r\n return null;\r\n },\r\n\r\n /**\r\n * Method: atPoint\r\n * Determins whether the feature intersects with the specified location.\r\n * \r\n * Parameters: \r\n * lonlat - {|Object} OpenLayers.LonLat or an\r\n * object with a 'lon' and 'lat' properties.\r\n * toleranceLon - {float} Optional tolerance in Geometric Coords\r\n * toleranceLat - {float} Optional tolerance in Geographic Coords\r\n * \r\n * Returns:\r\n * {Boolean} Whether or not the feature is at the specified location\r\n */\r\n atPoint: function(lonlat, toleranceLon, toleranceLat) {\r\n var atPoint = false;\r\n if(this.geometry) {\r\n atPoint = this.geometry.atPoint(lonlat, toleranceLon, \r\n toleranceLat);\r\n }\r\n return atPoint;\r\n },\r\n\r\n /**\r\n * Method: destroyPopup\r\n * HACK - we need to decide if all vector features should be able to\r\n * delete popups\r\n */\r\n destroyPopup: function() {\r\n // pass\r\n },\r\n\r\n /**\r\n * Method: move\r\n * Moves the feature and redraws it at its new location\r\n *\r\n * Parameters:\r\n * location - { or } the\r\n * location to which to move the feature.\r\n */\r\n move: function(location) {\r\n\r\n if(!this.layer || !this.geometry.move){\r\n //do nothing if no layer or immoveable geometry\r\n return undefined;\r\n }\r\n\r\n var pixel;\r\n if (location.CLASS_NAME == \"OpenLayers.LonLat\") {\r\n pixel = this.layer.getViewPortPxFromLonLat(location);\r\n } else {\r\n pixel = location;\r\n }\r\n \r\n var lastPixel = this.layer.getViewPortPxFromLonLat(this.geometry.getBounds().getCenterLonLat());\r\n var res = this.layer.map.getResolution();\r\n this.geometry.move(res * (pixel.x - lastPixel.x),\r\n res * (lastPixel.y - pixel.y));\r\n this.layer.drawFeature(this);\r\n return lastPixel;\r\n },\r\n \r\n /**\r\n * Method: toState\r\n * Sets the new state\r\n *\r\n * Parameters:\r\n * state - {String} \r\n */\r\n toState: function(state) {\r\n if (state == OpenLayers.State.UPDATE) {\r\n switch (this.state) {\r\n case OpenLayers.State.UNKNOWN:\r\n case OpenLayers.State.DELETE:\r\n this.state = state;\r\n break;\r\n case OpenLayers.State.UPDATE:\r\n case OpenLayers.State.INSERT:\r\n break;\r\n }\r\n } else if (state == OpenLayers.State.INSERT) {\r\n switch (this.state) {\r\n case OpenLayers.State.UNKNOWN:\r\n break;\r\n default:\r\n this.state = state;\r\n break;\r\n }\r\n } else if (state == OpenLayers.State.DELETE) {\r\n switch (this.state) {\r\n case OpenLayers.State.INSERT:\r\n // the feature should be destroyed\r\n break;\r\n case OpenLayers.State.DELETE:\r\n break;\r\n case OpenLayers.State.UNKNOWN:\r\n case OpenLayers.State.UPDATE:\r\n this.state = state;\r\n break;\r\n }\r\n } else if (state == OpenLayers.State.UNKNOWN) {\r\n this.state = state;\r\n }\r\n },\r\n \r\n CLASS_NAME: \"OpenLayers.Feature.Vector\"\r\n});\r\n\r\n\r\n/**\r\n * Constant: OpenLayers.Feature.Vector.style\r\n * OpenLayers features can have a number of style attributes. The 'default' \r\n * style will typically be used if no other style is specified. These\r\n * styles correspond for the most part, to the styling properties defined\r\n * by the SVG standard. \r\n * Information on fill properties: http://www.w3.org/TR/SVG/painting.html#FillProperties\r\n * Information on stroke properties: http://www.w3.org/TR/SVG/painting.html#StrokeProperties\r\n *\r\n * Symbolizer properties:\r\n * fill - {Boolean} Set to false if no fill is desired.\r\n * fillColor - {String} Hex fill color. Default is \"#ee9900\".\r\n * fillOpacity - {Number} Fill opacity (0-1). Default is 0.4 \r\n * stroke - {Boolean} Set to false if no stroke is desired.\r\n * strokeColor - {String} Hex stroke color. Default is \"#ee9900\".\r\n * strokeOpacity - {Number} Stroke opacity (0-1). Default is 1.\r\n * strokeWidth - {Number} Pixel stroke width. Default is 1.\r\n * strokeLinecap - {String} Stroke cap type. Default is \"round\". [butt | round | square]\r\n * strokeDashstyle - {String} Stroke dash style. Default is \"solid\". [dot | dash | dashdot | longdash | longdashdot | solid]\r\n * graphic - {Boolean} Set to false if no graphic is desired.\r\n * pointRadius - {Number} Pixel point radius. Default is 6.\r\n * pointerEvents - {String} Default is \"visiblePainted\".\r\n * cursor - {String} Default is \"\".\r\n * externalGraphic - {String} Url to an external graphic that will be used for rendering points.\r\n * graphicWidth - {Number} Pixel width for sizing an external graphic.\r\n * graphicHeight - {Number} Pixel height for sizing an external graphic.\r\n * graphicOpacity - {Number} Opacity (0-1) for an external graphic.\r\n * graphicXOffset - {Number} Pixel offset along the positive x axis for displacing an external graphic.\r\n * graphicYOffset - {Number} Pixel offset along the positive y axis for displacing an external graphic.\r\n * rotation - {Number} For point symbolizers, this is the rotation of a graphic in the clockwise direction about its center point (or any point off center as specified by graphicXOffset and graphicYOffset).\r\n * graphicZIndex - {Number} The integer z-index value to use in rendering.\r\n * graphicName - {String} Named graphic to use when rendering points. Supported values include \"circle\" (default),\r\n * \"square\", \"star\", \"x\", \"cross\", \"triangle\".\r\n * graphicTitle - {String} Tooltip when hovering over a feature. *deprecated*, use title instead\r\n * title - {String} Tooltip when hovering over a feature. Not supported by the canvas renderer.\r\n * backgroundGraphic - {String} Url to a graphic to be used as the background under an externalGraphic.\r\n * backgroundGraphicZIndex - {Number} The integer z-index value to use in rendering the background graphic.\r\n * backgroundXOffset - {Number} The x offset (in pixels) for the background graphic.\r\n * backgroundYOffset - {Number} The y offset (in pixels) for the background graphic.\r\n * backgroundHeight - {Number} The height of the background graphic. If not provided, the graphicHeight will be used.\r\n * backgroundWidth - {Number} The width of the background width. If not provided, the graphicWidth will be used.\r\n * label - {String} The text for an optional label. For browsers that use the canvas renderer, this requires either\r\n * fillText or mozDrawText to be available.\r\n * labelAlign - {String} Label alignment. This specifies the insertion point relative to the text. It is a string\r\n * composed of two characters. The first character is for the horizontal alignment, the second for the vertical\r\n * alignment. Valid values for horizontal alignment: \"l\"=left, \"c\"=center, \"r\"=right. Valid values for vertical\r\n * alignment: \"t\"=top, \"m\"=middle, \"b\"=bottom. Example values: \"lt\", \"cm\", \"rb\". Default is \"cm\".\r\n * labelXOffset - {Number} Pixel offset along the positive x axis for displacing the label. Not supported by the canvas renderer.\r\n * labelYOffset - {Number} Pixel offset along the positive y axis for displacing the label. Not supported by the canvas renderer.\r\n * labelSelect - {Boolean} If set to true, labels will be selectable using SelectFeature or similar controls.\r\n * Default is false.\r\n * labelOutlineColor - {String} The color of the label outline. Default is 'white'. Only supported by the canvas & SVG renderers.\r\n * labelOutlineWidth - {Number} The width of the label outline. Default is 3, set to 0 or null to disable. Only supported by the SVG renderers.\r\n * labelOutlineOpacity - {Number} The opacity (0-1) of the label outline. Default is fontOpacity. Only supported by the canvas & SVG renderers.\r\n * fontColor - {String} The font color for the label, to be provided like CSS.\r\n * fontOpacity - {Number} Opacity (0-1) for the label\r\n * fontFamily - {String} The font family for the label, to be provided like in CSS.\r\n * fontSize - {String} The font size for the label, to be provided like in CSS.\r\n * fontStyle - {String} The font style for the label, to be provided like in CSS.\r\n * fontWeight - {String} The font weight for the label, to be provided like in CSS.\r\n * display - {String} Symbolizers will have no effect if display is set to \"none\". All other values have no effect.\r\n */ \r\nOpenLayers.Feature.Vector.style = {\r\n 'default': {\r\n fillColor: \"#ee9900\",\r\n fillOpacity: 0.4, \r\n hoverFillColor: \"white\",\r\n hoverFillOpacity: 0.8,\r\n strokeColor: \"#ee9900\",\r\n strokeOpacity: 1,\r\n strokeWidth: 1,\r\n strokeLinecap: \"round\",\r\n strokeDashstyle: \"solid\",\r\n hoverStrokeColor: \"red\",\r\n hoverStrokeOpacity: 1,\r\n hoverStrokeWidth: 0.2,\r\n pointRadius: 6,\r\n hoverPointRadius: 1,\r\n hoverPointUnit: \"%\",\r\n pointerEvents: \"visiblePainted\",\r\n cursor: \"inherit\",\r\n fontColor: \"#000000\",\r\n labelAlign: \"cm\",\r\n labelOutlineColor: \"white\",\r\n labelOutlineWidth: 3\r\n },\r\n 'select': {\r\n fillColor: \"blue\",\r\n fillOpacity: 0.4, \r\n hoverFillColor: \"white\",\r\n hoverFillOpacity: 0.8,\r\n strokeColor: \"blue\",\r\n strokeOpacity: 1,\r\n strokeWidth: 2,\r\n strokeLinecap: \"round\",\r\n strokeDashstyle: \"solid\",\r\n hoverStrokeColor: \"red\",\r\n hoverStrokeOpacity: 1,\r\n hoverStrokeWidth: 0.2,\r\n pointRadius: 6,\r\n hoverPointRadius: 1,\r\n hoverPointUnit: \"%\",\r\n pointerEvents: \"visiblePainted\",\r\n cursor: \"pointer\",\r\n fontColor: \"#000000\",\r\n labelAlign: \"cm\",\r\n labelOutlineColor: \"white\",\r\n labelOutlineWidth: 3\r\n\r\n },\r\n 'temporary': {\r\n fillColor: \"#66cccc\",\r\n fillOpacity: 0.2, \r\n hoverFillColor: \"white\",\r\n hoverFillOpacity: 0.8,\r\n strokeColor: \"#66cccc\",\r\n strokeOpacity: 1,\r\n strokeLinecap: \"round\",\r\n strokeWidth: 2,\r\n strokeDashstyle: \"solid\",\r\n hoverStrokeColor: \"red\",\r\n hoverStrokeOpacity: 1,\r\n hoverStrokeWidth: 0.2,\r\n pointRadius: 6,\r\n hoverPointRadius: 1,\r\n hoverPointUnit: \"%\",\r\n pointerEvents: \"visiblePainted\",\r\n cursor: \"inherit\",\r\n fontColor: \"#000000\",\r\n labelAlign: \"cm\",\r\n labelOutlineColor: \"white\",\r\n labelOutlineWidth: 3\r\n\r\n },\r\n 'delete': {\r\n display: \"none\"\r\n }\r\n}; \r\n/* ======================================================================\r\n OpenLayers/Geometry.js\r\n ====================================================================== */\r\n\r\n/* Copyright (c) 2006-2015 by OpenLayers Contributors (see authors.txt for\r\n * full list of contributors). Published under the 2-clause BSD license.\r\n * See license.txt in the OpenLayers distribution or repository for the\r\n * full text of the license. */\r\n \r\n/**\r\n * @requires OpenLayers/BaseTypes/Class.js\r\n */\r\n\r\n/**\r\n * Class: OpenLayers.Geometry\r\n * A Geometry is a description of a geographic object. Create an instance of\r\n * this class with the constructor. This is a base class,\r\n * typical geometry types are described by subclasses of this class.\r\n *\r\n * Note that if you use the method, you must\r\n * explicitly include the OpenLayers.Format.WKT in your build.\r\n */\r\nOpenLayers.Geometry = OpenLayers.Class({\r\n\r\n /**\r\n * Property: id\r\n * {String} A unique identifier for this geometry.\r\n */\r\n id: null,\r\n\r\n /**\r\n * Property: parent\r\n * {}This is set when a Geometry is added as component\r\n * of another geometry\r\n */\r\n parent: null,\r\n\r\n /**\r\n * Property: bounds \r\n * {} The bounds of this geometry\r\n */\r\n bounds: null,\r\n\r\n /**\r\n * Constructor: OpenLayers.Geometry\r\n * Creates a geometry object. \r\n */\r\n initialize: function() {\r\n this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME+ \"_\");\r\n },\r\n \r\n /**\r\n * Method: destroy\r\n * Destroy this geometry.\r\n */\r\n destroy: function() {\r\n this.id = null;\r\n this.bounds = null;\r\n },\r\n \r\n /**\r\n * APIMethod: clone\r\n * Create a clone of this geometry. Does not set any non-standard\r\n * properties of the cloned geometry.\r\n * \r\n * Returns:\r\n * {} An exact clone of this geometry.\r\n */\r\n clone: function() {\r\n return new OpenLayers.Geometry();\r\n },\r\n \r\n /**\r\n * Method: setBounds\r\n * Set the bounds for this Geometry.\r\n * \r\n * Parameters:\r\n * bounds - {} \r\n */\r\n setBounds: function(bounds) {\r\n if (bounds) {\r\n this.bounds = bounds.clone();\r\n }\r\n },\r\n \r\n /**\r\n * Method: clearBounds\r\n * Nullify this components bounds and that of its parent as well.\r\n */\r\n clearBounds: function() {\r\n this.bounds = null;\r\n if (this.parent) {\r\n this.parent.clearBounds();\r\n } \r\n },\r\n \r\n /**\r\n * Method: extendBounds\r\n * Extend the existing bounds to include the new bounds. \r\n * If geometry's bounds is not yet set, then set a new Bounds.\r\n * \r\n * Parameters:\r\n * newBounds - {} \r\n */\r\n extendBounds: function(newBounds){\r\n var bounds = this.getBounds();\r\n if (!bounds) {\r\n this.setBounds(newBounds);\r\n } else {\r\n this.bounds.extend(newBounds);\r\n }\r\n },\r\n \r\n /**\r\n * APIMethod: getBounds\r\n * Get the bounds for this Geometry. If bounds is not set, it \r\n * is calculated again, this makes queries faster.\r\n * \r\n * Returns:\r\n * {}\r\n */\r\n getBounds: function() {\r\n if (this.bounds == null) {\r\n this.calculateBounds();\r\n }\r\n return this.bounds;\r\n },\r\n \r\n /** \r\n * APIMethod: calculateBounds\r\n * Recalculate the bounds for the geometry. \r\n */\r\n calculateBounds: function() {\r\n //\r\n // This should be overridden by subclasses.\r\n //\r\n },\r\n \r\n /**\r\n * APIMethod: distanceTo\r\n * Calculate the closest distance between two geometries (on the x-y plane).\r\n *\r\n * Parameters:\r\n * geometry - {} The target geometry.\r\n * options - {Object} Optional properties for configuring the distance\r\n * calculation.\r\n *\r\n * Valid options depend on the specific geometry type.\r\n * \r\n * Returns:\r\n * {Number | Object} The distance between this geometry and the target.\r\n * If details is true, the return will be an object with distance,\r\n * x0, y0, x1, and x2 properties. The x0 and y0 properties represent\r\n * the coordinates of the closest point on this geometry. The x1 and y1\r\n * properties represent the coordinates of the closest point on the\r\n * target geometry.\r\n */\r\n distanceTo: function(geometry, options) {\r\n },\r\n \r\n /**\r\n * APIMethod: getVertices\r\n * Return a list of all points in this geometry.\r\n *\r\n * Parameters:\r\n * nodes - {Boolean} For lines, only return vertices that are\r\n * endpoints. If false, for lines, only vertices that are not\r\n * endpoints will be returned. If not provided, all vertices will\r\n * be returned.\r\n *\r\n * Returns:\r\n * {Array} A list of all vertices in the geometry.\r\n */\r\n getVertices: function(nodes) {\r\n },\r\n\r\n /**\r\n * Method: atPoint\r\n * Note - This is only an approximation based on the bounds of the \r\n * geometry.\r\n * \r\n * Parameters:\r\n * lonlat - {|Object} OpenLayers.LonLat or an\r\n * object with a 'lon' and 'lat' properties.\r\n * toleranceLon - {float} Optional tolerance in Geometric Coords\r\n * toleranceLat - {float} Optional tolerance in Geographic Coords\r\n * \r\n * Returns:\r\n * {Boolean} Whether or not the geometry is at the specified location\r\n */\r\n atPoint: function(lonlat, toleranceLon, toleranceLat) {\r\n var atPoint = false;\r\n var bounds = this.getBounds();\r\n if ((bounds != null) && (lonlat != null)) {\r\n\r\n var dX = (toleranceLon != null) ? toleranceLon : 0;\r\n var dY = (toleranceLat != null) ? toleranceLat : 0;\r\n \r\n var toleranceBounds = \r\n new OpenLayers.Bounds(this.bounds.left - dX,\r\n this.bounds.bottom - dY,\r\n this.bounds.right + dX,\r\n this.bounds.top + dY);\r\n\r\n atPoint = toleranceBounds.containsLonLat(lonlat);\r\n }\r\n return atPoint;\r\n },\r\n \r\n /**\r\n * Method: getLength\r\n * Calculate the length of this geometry. This method is defined in\r\n * subclasses.\r\n * \r\n * Returns:\r\n * {Float} The length of the collection by summing its parts\r\n */\r\n getLength: function() {\r\n //to be overridden by geometries that actually have a length\r\n //\r\n return 0.0;\r\n },\r\n\r\n /**\r\n * Method: getArea\r\n * Calculate the area of this geometry. This method is defined in subclasses.\r\n * \r\n * Returns:\r\n * {Float} The area of the collection by summing its parts\r\n */\r\n getArea: function() {\r\n //to be overridden by geometries that actually have an area\r\n //\r\n return 0.0;\r\n },\r\n \r\n /**\r\n * APIMethod: getCentroid\r\n * Calculate the centroid of this geometry. This method is defined in subclasses.\r\n *\r\n * Returns:\r\n * {} The centroid of the collection\r\n */\r\n getCentroid: function() {\r\n return null;\r\n },\r\n\r\n /**\r\n * Method: toString\r\n * Returns a text representation of the geometry. If the WKT format is\r\n * included in a build, this will be the Well-Known Text \r\n * representation.\r\n *\r\n * Returns:\r\n * {String} String representation of this geometry.\r\n */\r\n toString: function() {\r\n var string;\r\n if (OpenLayers.Format && OpenLayers.Format.WKT) {\r\n string = OpenLayers.Format.WKT.prototype.write(\r\n new OpenLayers.Feature.Vector(this)\r\n );\r\n } else {\r\n string = Object.prototype.toString.call(this);\r\n }\r\n return string;\r\n },\r\n\r\n CLASS_NAME: \"OpenLayers.Geometry\"\r\n});\r\n\r\n/**\r\n * Function: OpenLayers.Geometry.fromWKT\r\n * Generate a geometry given a Well-Known Text string. For this method to\r\n * work, you must include the OpenLayers.Format.WKT in your build \r\n * explicitly.\r\n *\r\n * Parameters:\r\n * wkt - {String} A string representing the geometry in Well-Known Text.\r\n *\r\n * Returns:\r\n * {} A geometry of the appropriate class.\r\n */\r\nOpenLayers.Geometry.fromWKT = function(wkt) {\r\n var geom;\r\n if (OpenLayers.Format && OpenLayers.Format.WKT) {\r\n var format = OpenLayers.Geometry.fromWKT.format;\r\n if (!format) {\r\n format = new OpenLayers.Format.WKT();\r\n OpenLayers.Geometry.fromWKT.format = format;\r\n }\r\n var result = format.read(wkt);\r\n if (result instanceof OpenLayers.Feature.Vector) {\r\n geom = result.geometry;\r\n } else if (OpenLayers.Util.isArray(result)) {\r\n var len = result.length;\r\n var components = new Array(len);\r\n for (var i=0; i= seg2.x1 || seg2.x2 >= seg1.x1. In those\r\n * obvious cases where there is no intersection, the function should\r\n * not be called.\r\n *\r\n * Parameters:\r\n * seg1 - {Object} Object representing a segment with properties x1, y1, x2,\r\n * and y2. The start point is represented by x1 and y1. The end point\r\n * is represented by x2 and y2. Start and end are ordered so that x1 < x2.\r\n * seg2 - {Object} Object representing a segment with properties x1, y1, x2,\r\n * and y2. The start point is represented by x1 and y1. The end point\r\n * is represented by x2 and y2. Start and end are ordered so that x1 < x2.\r\n * options - {Object} Optional properties for calculating the intersection.\r\n *\r\n * Valid options:\r\n * point - {Boolean} Return the intersection point. If false, the actual\r\n * intersection point will not be calculated. If true and the segments\r\n * intersect, the intersection point will be returned. If true and\r\n * the segments do not intersect, false will be returned. If true and\r\n * the segments are coincident, true will be returned.\r\n * tolerance - {Number} If a non-null value is provided, if the segments are\r\n * within the tolerance distance, this will be considered an intersection.\r\n * In addition, if the point option is true and the calculated intersection\r\n * is within the tolerance distance of an end point, the endpoint will be\r\n * returned instead of the calculated intersection. Further, if the\r\n * intersection is within the tolerance of endpoints on both segments, or\r\n * if two segment endpoints are within the tolerance distance of eachother\r\n * (but no intersection is otherwise calculated), an endpoint on the\r\n * first segment provided will be returned.\r\n *\r\n * Returns:\r\n * {Boolean | } The two segments intersect.\r\n * If the point argument is true, the return will be the intersection\r\n * point or false if none exists. If point is true and the segments\r\n * are coincident, return will be true (and the instersection is equal\r\n * to the shorter segment).\r\n */\r\nOpenLayers.Geometry.segmentsIntersect = function(seg1, seg2, options) {\r\n var point = options && options.point;\r\n var tolerance = options && options.tolerance;\r\n var intersection = false;\r\n var x11_21 = seg1.x1 - seg2.x1;\r\n var y11_21 = seg1.y1 - seg2.y1;\r\n var x12_11 = seg1.x2 - seg1.x1;\r\n var y12_11 = seg1.y2 - seg1.y1;\r\n var y22_21 = seg2.y2 - seg2.y1;\r\n var x22_21 = seg2.x2 - seg2.x1;\r\n var d = (y22_21 * x12_11) - (x22_21 * y12_11);\r\n var n1 = (x22_21 * y11_21) - (y22_21 * x11_21);\r\n var n2 = (x12_11 * y11_21) - (y12_11 * x11_21);\r\n if(d == 0) {\r\n // parallel\r\n if(n1 == 0 && n2 == 0) {\r\n // coincident\r\n intersection = true;\r\n }\r\n } else {\r\n var along1 = n1 / d;\r\n var along2 = n2 / d;\r\n if(along1 >= 0 && along1 <= 1 && along2 >=0 && along2 <= 1) {\r\n // intersect\r\n if(!point) {\r\n intersection = true;\r\n } else {\r\n // calculate the intersection point\r\n var x = seg1.x1 + (along1 * x12_11);\r\n var y = seg1.y1 + (along1 * y12_11);\r\n intersection = new OpenLayers.Geometry.Point(x, y);\r\n }\r\n }\r\n }\r\n if(tolerance) {\r\n var dist;\r\n if(intersection) {\r\n if(point) {\r\n var segs = [seg1, seg2];\r\n var seg, x, y;\r\n // check segment endpoints for proximity to intersection\r\n // set intersection to first endpoint within the tolerance\r\n outer: for(var i=0; i<2; ++i) {\r\n seg = segs[i];\r\n for(var j=1; j<3; ++j) {\r\n x = seg[\"x\" + j];\r\n y = seg[\"y\" + j];\r\n dist = Math.sqrt(\r\n Math.pow(x - intersection.x, 2) +\r\n Math.pow(y - intersection.y, 2)\r\n );\r\n if(dist < tolerance) {\r\n intersection.x = x;\r\n intersection.y = y;\r\n break outer;\r\n }\r\n }\r\n }\r\n \r\n }\r\n } else {\r\n // no calculated intersection, but segments could be within\r\n // the tolerance of one another\r\n var segs = [seg1, seg2];\r\n var source, target, x, y, p, result;\r\n // check segment endpoints for proximity to intersection\r\n // set intersection to first endpoint within the tolerance\r\n outer: for(var i=0; i<2; ++i) {\r\n source = segs[i];\r\n target = segs[(i+1)%2];\r\n for(var j=1; j<3; ++j) {\r\n p = {x: source[\"x\"+j], y: source[\"y\"+j]};\r\n result = OpenLayers.Geometry.distanceToSegment(p, target);\r\n if(result.distance < tolerance) {\r\n if(point) {\r\n intersection = new OpenLayers.Geometry.Point(p.x, p.y);\r\n } else {\r\n intersection = true;\r\n }\r\n break outer;\r\n }\r\n }\r\n }\r\n }\r\n }\r\n return intersection;\r\n};\r\n\r\n/**\r\n * Function: OpenLayers.Geometry.distanceToSegment\r\n *\r\n * Parameters:\r\n * point - {Object} An object with x and y properties representing the\r\n * point coordinates.\r\n * segment - {Object} An object with x1, y1, x2, and y2 properties\r\n * representing endpoint coordinates.\r\n *\r\n * Returns:\r\n * {Object} An object with distance, along, x, and y properties. The distance\r\n * will be the shortest distance between the input point and segment.\r\n * The x and y properties represent the coordinates along the segment\r\n * where the shortest distance meets the segment. The along attribute\r\n * describes how far between the two segment points the given point is.\r\n */\r\nOpenLayers.Geometry.distanceToSegment = function(point, segment) {\r\n var result = OpenLayers.Geometry.distanceSquaredToSegment(point, segment);\r\n result.distance = Math.sqrt(result.distance);\r\n return result;\r\n};\r\n\r\n/**\r\n * Function: OpenLayers.Geometry.distanceSquaredToSegment\r\n *\r\n * Usually the distanceToSegment function should be used. This variant however\r\n * can be used for comparisons where the exact distance is not important.\r\n *\r\n * Parameters:\r\n * point - {Object} An object with x and y properties representing the\r\n * point coordinates.\r\n * segment - {Object} An object with x1, y1, x2, and y2 properties\r\n * representing endpoint coordinates.\r\n *\r\n * Returns:\r\n * {Object} An object with squared distance, along, x, and y properties.\r\n * The distance will be the shortest distance between the input point and\r\n * segment. The x and y properties represent the coordinates along the\r\n * segment where the shortest distance meets the segment. The along\r\n * attribute describes how far between the two segment points the given\r\n * point is.\r\n */\r\nOpenLayers.Geometry.distanceSquaredToSegment = function(point, segment) {\r\n var x0 = point.x;\r\n var y0 = point.y;\r\n var x1 = segment.x1;\r\n var y1 = segment.y1;\r\n var x2 = segment.x2;\r\n var y2 = segment.y2;\r\n var dx = x2 - x1;\r\n var dy = y2 - y1;\r\n var along = (dx == 0 && dy == 0) ? 0 : ((dx * (x0 - x1)) + (dy * (y0 - y1))) /\r\n (Math.pow(dx, 2) + Math.pow(dy, 2));\r\n var x, y;\r\n if(along <= 0.0) {\r\n x = x1;\r\n y = y1;\r\n } else if(along >= 1.0) {\r\n x = x2;\r\n y = y2;\r\n } else {\r\n x = x1 + along * dx;\r\n y = y1 + along * dy;\r\n }\r\n return {\r\n distance: Math.pow(x - x0, 2) + Math.pow(y - y0, 2),\r\n x: x, y: y,\r\n along: along\r\n };\r\n};\r\n/* ======================================================================\r\n OpenLayers/Geometry/Point.js\r\n ====================================================================== */\r\n\r\n/* Copyright (c) 2006-2015 by OpenLayers Contributors (see authors.txt for\r\n * full list of contributors). Published under the 2-clause BSD license.\r\n * See license.txt in the OpenLayers distribution or repository for the\r\n * full text of the license. */\r\n\r\n/**\r\n * @requires OpenLayers/Geometry.js\r\n */\r\n\r\n/**\r\n * Class: OpenLayers.Geometry.Point\r\n * Point geometry class. \r\n * \r\n * Inherits from:\r\n * - \r\n */\r\nOpenLayers.Geometry.Point = OpenLayers.Class(OpenLayers.Geometry, {\r\n\r\n /** \r\n * APIProperty: x \r\n * {float} \r\n */\r\n x: null,\r\n\r\n /** \r\n * APIProperty: y \r\n * {float} \r\n */\r\n y: null,\r\n\r\n /**\r\n * Constructor: OpenLayers.Geometry.Point\r\n * Construct a point geometry.\r\n *\r\n * Parameters:\r\n * x - {float} \r\n * y - {float}\r\n * \r\n */\r\n initialize: function(x, y) {\r\n OpenLayers.Geometry.prototype.initialize.apply(this, arguments);\r\n \r\n this.x = parseFloat(x);\r\n this.y = parseFloat(y);\r\n },\r\n\r\n /**\r\n * APIMethod: clone\r\n * \r\n * Returns:\r\n * {} An exact clone of this OpenLayers.Geometry.Point\r\n */\r\n clone: function(obj) {\r\n if (obj == null) {\r\n obj = new OpenLayers.Geometry.Point(this.x, this.y);\r\n }\r\n\r\n // catch any randomly tagged-on properties\r\n OpenLayers.Util.applyDefaults(obj, this);\r\n\r\n return obj;\r\n },\r\n\r\n /** \r\n * Method: calculateBounds\r\n * Create a new Bounds based on the lon/lat\r\n */\r\n calculateBounds: function () {\r\n this.bounds = new OpenLayers.Bounds(this.x, this.y,\r\n this.x, this.y);\r\n },\r\n\r\n /**\r\n * APIMethod: distanceTo\r\n * Calculate the closest distance between two geometries (on the x-y plane).\r\n *\r\n * Parameters:\r\n * geometry - {} The target geometry.\r\n * options - {Object} Optional properties for configuring the distance\r\n * calculation.\r\n *\r\n * Valid options:\r\n * details - {Boolean} Return details from the distance calculation.\r\n * Default is false.\r\n * edge - {Boolean} Calculate the distance from this geometry to the\r\n * nearest edge of the target geometry. Default is true. If true,\r\n * calling distanceTo from a geometry that is wholly contained within\r\n * the target will result in a non-zero distance. If false, whenever\r\n * geometries intersect, calling distanceTo will return 0. If false,\r\n * details cannot be returned.\r\n *\r\n * Returns:\r\n * {Number | Object} The distance between this geometry and the target.\r\n * If details is true, the return will be an object with distance,\r\n * x0, y0, x1, and x2 properties. The x0 and y0 properties represent\r\n * the coordinates of the closest point on this geometry. The x1 and y1\r\n * properties represent the coordinates of the closest point on the\r\n * target geometry.\r\n */\r\n distanceTo: function(geometry, options) {\r\n var edge = !(options && options.edge === false);\r\n var details = edge && options && options.details;\r\n var distance, x0, y0, x1, y1, result;\r\n if(geometry instanceof OpenLayers.Geometry.Point) {\r\n x0 = this.x;\r\n y0 = this.y;\r\n x1 = geometry.x;\r\n y1 = geometry.y;\r\n distance = Math.sqrt(Math.pow(x0 - x1, 2) + Math.pow(y0 - y1, 2));\r\n result = !details ?\r\n distance : {x0: x0, y0: y0, x1: x1, y1: y1, distance: distance};\r\n } else {\r\n result = geometry.distanceTo(this, options);\r\n if(details) {\r\n // switch coord order since this geom is target\r\n result = {\r\n x0: result.x1, y0: result.y1,\r\n x1: result.x0, y1: result.y0,\r\n distance: result.distance\r\n };\r\n }\r\n }\r\n return result;\r\n },\r\n \r\n /** \r\n * APIMethod: equals\r\n * Determine whether another geometry is equivalent to this one. Geometries\r\n * are considered equivalent if all components have the same coordinates.\r\n * \r\n * Parameters:\r\n * geom - {} The geometry to test. \r\n *\r\n * Returns:\r\n * {Boolean} The supplied geometry is equivalent to this geometry.\r\n */\r\n equals: function(geom) {\r\n var equals = false;\r\n if (geom != null) {\r\n equals = ((this.x == geom.x && this.y == geom.y) ||\r\n (isNaN(this.x) && isNaN(this.y) && isNaN(geom.x) && isNaN(geom.y)));\r\n }\r\n return equals;\r\n },\r\n \r\n /**\r\n * Method: toShortString\r\n *\r\n * Returns:\r\n * {String} Shortened String representation of Point object. \r\n * (ex. \"5, 42\")\r\n */\r\n toShortString: function() {\r\n return (this.x + \", \" + this.y);\r\n },\r\n \r\n /**\r\n * APIMethod: move\r\n * Moves a geometry by the given displacement along positive x and y axes.\r\n * This modifies the position of the geometry and clears the cached\r\n * bounds.\r\n *\r\n * Parameters:\r\n * x - {Float} Distance to move geometry in positive x direction. \r\n * y - {Float} Distance to move geometry in positive y direction.\r\n */\r\n move: function(x, y) {\r\n this.x = this.x + x;\r\n this.y = this.y + y;\r\n this.clearBounds();\r\n },\r\n\r\n /**\r\n * APIMethod: rotate\r\n * Rotate a point around another.\r\n *\r\n * Parameters:\r\n * angle - {Float} Rotation angle in degrees (measured counterclockwise\r\n * from the positive x-axis)\r\n * origin - {} Center point for the rotation\r\n */\r\n rotate: function(angle, origin) {\r\n angle *= Math.PI / 180;\r\n var radius = this.distanceTo(origin);\r\n var theta = angle + Math.atan2(this.y - origin.y, this.x - origin.x);\r\n this.x = origin.x + (radius * Math.cos(theta));\r\n this.y = origin.y + (radius * Math.sin(theta));\r\n this.clearBounds();\r\n },\r\n \r\n /**\r\n * APIMethod: getCentroid\r\n *\r\n * Returns:\r\n * {} The centroid of the collection\r\n */\r\n getCentroid: function() {\r\n return new OpenLayers.Geometry.Point(this.x, this.y);\r\n },\r\n\r\n /**\r\n * APIMethod: resize\r\n * Resize a point relative to some origin. For points, this has the effect\r\n * of scaling a vector (from the origin to the point). This method is\r\n * more useful on geometry collection subclasses.\r\n *\r\n * Parameters:\r\n * scale - {Float} Ratio of the new distance from the origin to the old\r\n * distance from the origin. A scale of 2 doubles the\r\n * distance between the point and origin.\r\n * origin - {} Point of origin for resizing\r\n * ratio - {Float} Optional x:y ratio for resizing. Default ratio is 1.\r\n * \r\n * Returns:\r\n * {} - The current geometry. \r\n */\r\n resize: function(scale, origin, ratio) {\r\n ratio = (ratio == undefined) ? 1 : ratio;\r\n this.x = origin.x + (scale * ratio * (this.x - origin.x));\r\n this.y = origin.y + (scale * (this.y - origin.y));\r\n this.clearBounds();\r\n return this;\r\n },\r\n \r\n /**\r\n * APIMethod: intersects\r\n * Determine if the input geometry intersects this one.\r\n *\r\n * Parameters:\r\n * geometry - {} Any type of geometry.\r\n *\r\n * Returns:\r\n * {Boolean} The input geometry intersects this one.\r\n */\r\n intersects: function(geometry) {\r\n var intersect = false;\r\n if(geometry.CLASS_NAME == \"OpenLayers.Geometry.Point\") {\r\n intersect = this.equals(geometry);\r\n } else {\r\n intersect = geometry.intersects(this);\r\n }\r\n return intersect;\r\n },\r\n \r\n /**\r\n * APIMethod: transform\r\n * Translate the x,y properties of the point from source to dest.\r\n * \r\n * Parameters:\r\n * source - {} \r\n * dest - {}\r\n * \r\n * Returns:\r\n * {} \r\n */\r\n transform: function(source, dest) {\r\n if ((source && dest)) {\r\n OpenLayers.Projection.transform(\r\n this, source, dest); \r\n this.bounds = null;\r\n } \r\n return this;\r\n },\r\n\r\n /**\r\n * APIMethod: getVertices\r\n * Return a list of all points in this geometry.\r\n *\r\n * Parameters:\r\n * nodes - {Boolean} For lines, only return vertices that are\r\n * endpoints. If false, for lines, only vertices that are not\r\n * endpoints will be returned. If not provided, all vertices will\r\n * be returned.\r\n *\r\n * Returns:\r\n * {Array} A list of all vertices in the geometry.\r\n */\r\n getVertices: function(nodes) {\r\n return [this];\r\n },\r\n\r\n CLASS_NAME: \"OpenLayers.Geometry.Point\"\r\n});\r\n/* ======================================================================\r\n OpenLayers/Geometry/Collection.js\r\n ====================================================================== */\r\n\r\n/* Copyright (c) 2006-2015 by OpenLayers Contributors (see authors.txt for\r\n * full list of contributors). Published under the 2-clause BSD license.\r\n * See license.txt in the OpenLayers distribution or repository for the\r\n * full text of the license. */\r\n\r\n/**\r\n * @requires OpenLayers/Geometry.js\r\n */\r\n\r\n/**\r\n * Class: OpenLayers.Geometry.Collection\r\n * A Collection is exactly what it sounds like: A collection of different \r\n * Geometries. These are stored in the local parameter (which\r\n * can be passed as a parameter to the constructor). \r\n * \r\n * As new geometries are added to the collection, they are NOT cloned. \r\n * When removing geometries, they need to be specified by reference (ie you \r\n * have to pass in the *exact* geometry to be removed).\r\n * \r\n * The and functions here merely iterate through\r\n * the components, summing their respective areas and lengths.\r\n *\r\n * Create a new instance with the constructor.\r\n *\r\n * Inherits from:\r\n * - \r\n */\r\nOpenLayers.Geometry.Collection = OpenLayers.Class(OpenLayers.Geometry, {\r\n\r\n /**\r\n * APIProperty: components\r\n * {Array()} The component parts of this geometry\r\n */\r\n components: null,\r\n \r\n /**\r\n * Property: componentTypes\r\n * {Array(String)} An array of class names representing the types of\r\n * components that the collection can include. A null value means the\r\n * component types are not restricted.\r\n */\r\n componentTypes: null,\r\n\r\n /**\r\n * Constructor: OpenLayers.Geometry.Collection\r\n * Creates a Geometry Collection -- a list of geoms.\r\n *\r\n * Parameters: \r\n * components - {Array()} Optional array of geometries\r\n *\r\n */\r\n initialize: function (components) {\r\n OpenLayers.Geometry.prototype.initialize.apply(this, arguments);\r\n this.components = [];\r\n if (components != null) {\r\n this.addComponents(components);\r\n }\r\n },\r\n\r\n /**\r\n * APIMethod: destroy\r\n * Destroy this geometry.\r\n */\r\n destroy: function () {\r\n this.components.length = 0;\r\n this.components = null;\r\n OpenLayers.Geometry.prototype.destroy.apply(this, arguments);\r\n },\r\n\r\n /**\r\n * APIMethod: clone\r\n * Clone this geometry.\r\n *\r\n * Returns:\r\n * {} An exact clone of this collection\r\n */\r\n clone: function() {\r\n var Constructor = OpenLayers.Util.getConstructor(this.CLASS_NAME);\r\n var geometry = new Constructor();\r\n for(var i=0, len=this.components.length; i)} An array of geometries to add\r\n */\r\n addComponents: function(components){\r\n if(!(OpenLayers.Util.isArray(components))) {\r\n components = [components];\r\n }\r\n for(var i=0, len=components.length; i} A geometry to add\r\n * index - {int} Optional index into the array to insert the component\r\n *\r\n * Returns:\r\n * {Boolean} The component geometry was successfully added\r\n */ \r\n addComponent: function(component, index) {\r\n var added = false;\r\n if(component) {\r\n if(this.componentTypes == null ||\r\n (OpenLayers.Util.indexOf(this.componentTypes,\r\n component.CLASS_NAME) > -1)) {\r\n\r\n if(index != null && (index < this.components.length)) {\r\n var components1 = this.components.slice(0, index);\r\n var components2 = this.components.slice(index, \r\n this.components.length);\r\n components1.push(component);\r\n this.components = components1.concat(components2);\r\n } else {\r\n this.components.push(component);\r\n }\r\n component.parent = this;\r\n this.clearBounds();\r\n added = true;\r\n }\r\n }\r\n return added;\r\n },\r\n \r\n /**\r\n * APIMethod: removeComponents\r\n * Remove components from this geometry.\r\n *\r\n * Parameters:\r\n * components - {Array()} The components to be removed\r\n *\r\n * Returns: \r\n * {Boolean} A component was removed.\r\n */\r\n removeComponents: function(components) {\r\n var removed = false;\r\n\r\n if(!(OpenLayers.Util.isArray(components))) {\r\n components = [components];\r\n }\r\n for(var i=components.length-1; i>=0; --i) {\r\n removed = this.removeComponent(components[i]) || removed;\r\n }\r\n return removed;\r\n },\r\n \r\n /**\r\n * Method: removeComponent\r\n * Remove a component from this geometry.\r\n *\r\n * Parameters:\r\n * component - {} \r\n *\r\n * Returns: \r\n * {Boolean} The component was removed.\r\n */\r\n removeComponent: function(component) {\r\n \r\n OpenLayers.Util.removeItem(this.components, component);\r\n \r\n // clearBounds() so that it gets recalculated on the next call\r\n // to this.getBounds();\r\n this.clearBounds();\r\n return true;\r\n },\r\n\r\n /**\r\n * APIMethod: getLength\r\n * Calculate the length of this geometry\r\n *\r\n * Returns:\r\n * {Float} The length of the geometry\r\n */\r\n getLength: function() {\r\n var length = 0.0;\r\n for (var i=0, len=this.components.length; i.\r\n *\r\n * Returns:\r\n * {Float} The area of the collection by summing its parts\r\n */\r\n getArea: function() {\r\n var area = 0.0;\r\n for (var i=0, len=this.components.length; i} The spatial reference system\r\n * for the geometry coordinates. If not provided, Geographic/WGS84 is\r\n * assumed.\r\n * \r\n * Reference:\r\n * Robert. G. Chamberlain and William H. Duquette, \"Some Algorithms for\r\n * Polygons on a Sphere\", JPL Publication 07-03, Jet Propulsion\r\n * Laboratory, Pasadena, CA, June 2007 http://trs-new.jpl.nasa.gov/dspace/handle/2014/40409\r\n *\r\n * Returns:\r\n * {float} The approximate geodesic area of the geometry in square meters.\r\n */\r\n getGeodesicArea: function(projection) {\r\n var area = 0.0;\r\n for(var i=0, len=this.components.length; i} The centroid of the collection\r\n */\r\n getCentroid: function(weighted) {\r\n if (!weighted) {\r\n return this.components.length && this.components[0].getCentroid();\r\n }\r\n var len = this.components.length;\r\n if (!len) {\r\n return false;\r\n }\r\n \r\n var areas = [];\r\n var centroids = [];\r\n var areaSum = 0;\r\n var minArea = Number.MAX_VALUE;\r\n var component;\r\n for (var i=0; i 0) ? area : minArea;\r\n centroids.push(centroid);\r\n }\r\n len = areas.length;\r\n if (areaSum === 0) {\r\n // all the components in this collection have 0 area\r\n // probably a collection of points -- weight all the points the same\r\n for (var i=0; i} The spatial reference system\r\n * for the geometry coordinates. If not provided, Geographic/WGS84 is\r\n * assumed.\r\n * \r\n * Returns:\r\n * {Float} The appoximate geodesic length of the geometry in meters.\r\n */\r\n getGeodesicLength: function(projection) {\r\n var length = 0.0;\r\n for(var i=0, len=this.components.length; i} Center point for the rotation\r\n */\r\n rotate: function(angle, origin) {\r\n for(var i=0, len=this.components.length; i} Point of origin for resizing\r\n * ratio - {Float} Optional x:y ratio for resizing. Default ratio is 1.\r\n * \r\n * Returns:\r\n * {} - The current geometry. \r\n */\r\n resize: function(scale, origin, ratio) {\r\n for(var i=0; i} The target geometry.\r\n * options - {Object} Optional properties for configuring the distance\r\n * calculation.\r\n *\r\n * Valid options:\r\n * details - {Boolean} Return details from the distance calculation.\r\n * Default is false.\r\n * edge - {Boolean} Calculate the distance from this geometry to the\r\n * nearest edge of the target geometry. Default is true. If true,\r\n * calling distanceTo from a geometry that is wholly contained within\r\n * the target will result in a non-zero distance. If false, whenever\r\n * geometries intersect, calling distanceTo will return 0. If false,\r\n * details cannot be returned.\r\n *\r\n * Returns:\r\n * {Number | Object} The distance between this geometry and the target.\r\n * If details is true, the return will be an object with distance,\r\n * x0, y0, x1, and y1 properties. The x0 and y0 properties represent\r\n * the coordinates of the closest point on this geometry. The x1 and y1\r\n * properties represent the coordinates of the closest point on the\r\n * target geometry.\r\n */\r\n distanceTo: function(geometry, options) {\r\n var edge = !(options && options.edge === false);\r\n var details = edge && options && options.details;\r\n var result, best, distance;\r\n var min = Number.POSITIVE_INFINITY;\r\n for(var i=0, len=this.components.length; i} The geometry to test. \r\n *\r\n * Returns:\r\n * {Boolean} The supplied geometry is equivalent to this geometry.\r\n */\r\n equals: function(geometry) {\r\n var equivalent = true;\r\n if(!geometry || !geometry.CLASS_NAME ||\r\n (this.CLASS_NAME != geometry.CLASS_NAME)) {\r\n equivalent = false;\r\n } else if(!(OpenLayers.Util.isArray(geometry.components)) ||\r\n (geometry.components.length != this.components.length)) {\r\n equivalent = false;\r\n } else {\r\n for(var i=0, len=this.components.length; i} \r\n * dest - {}\r\n * \r\n * Returns:\r\n * {} \r\n */\r\n transform: function(source, dest) {\r\n if (source && dest) {\r\n for (var i=0, len=this.components.length; i} Any type of geometry.\r\n *\r\n * Returns:\r\n * {Boolean} The input geometry intersects this one.\r\n */\r\n intersects: function(geometry) {\r\n var intersect = false;\r\n for(var i=0, len=this.components.length; i constructor.\r\n *\r\n * Inherits from:\r\n * - \r\n * - \r\n */\r\nOpenLayers.Geometry.MultiPoint = OpenLayers.Class(\r\n OpenLayers.Geometry.Collection, {\r\n\r\n /**\r\n * Property: componentTypes\r\n * {Array(String)} An array of class names representing the types of\r\n * components that the collection can include. A null value means the\r\n * component types are not restricted.\r\n */\r\n componentTypes: [\"OpenLayers.Geometry.Point\"],\r\n\r\n /**\r\n * Constructor: OpenLayers.Geometry.MultiPoint\r\n * Create a new MultiPoint Geometry\r\n *\r\n * Parameters:\r\n * components - {Array()} \r\n *\r\n * Returns:\r\n * {}\r\n */\r\n\r\n /**\r\n * APIMethod: addPoint\r\n * Wrapper for \r\n *\r\n * Parameters:\r\n * point - {} Point to be added\r\n * index - {Integer} Optional index\r\n */\r\n addPoint: function(point, index) {\r\n this.addComponent(point, index);\r\n },\r\n \r\n /**\r\n * APIMethod: removePoint\r\n * Wrapper for \r\n *\r\n * Parameters:\r\n * point - {} Point to be removed\r\n */\r\n removePoint: function(point){\r\n this.removeComponent(point);\r\n },\r\n\r\n CLASS_NAME: \"OpenLayers.Geometry.MultiPoint\"\r\n});\r\n/* ======================================================================\r\n OpenLayers/Geometry/Curve.js\r\n ====================================================================== */\r\n\r\n/* Copyright (c) 2006-2015 by OpenLayers Contributors (see authors.txt for\r\n * full list of contributors). Published under the 2-clause BSD license.\r\n * See license.txt in the OpenLayers distribution or repository for the\r\n * full text of the license. */\r\n\r\n/**\r\n * @requires OpenLayers/Geometry/MultiPoint.js\r\n */\r\n\r\n/**\r\n * Class: OpenLayers.Geometry.Curve\r\n * A Curve is a MultiPoint, whose points are assumed to be connected. To \r\n * this end, we provide a \"getLength()\" function, which iterates through \r\n * the points, summing the distances between them. \r\n * \r\n * Inherits: \r\n * - \r\n */\r\nOpenLayers.Geometry.Curve = OpenLayers.Class(OpenLayers.Geometry.MultiPoint, {\r\n\r\n /**\r\n * Property: componentTypes\r\n * {Array(String)} An array of class names representing the types of \r\n * components that the collection can include. A null \r\n * value means the component types are not restricted.\r\n */\r\n componentTypes: [\"OpenLayers.Geometry.Point\"],\r\n\r\n /**\r\n * Constructor: OpenLayers.Geometry.Curve\r\n * \r\n * Parameters:\r\n * point - {Array()}\r\n */\r\n \r\n /**\r\n * APIMethod: getLength\r\n * \r\n * Returns:\r\n * {Float} The length of the curve\r\n */\r\n getLength: function() {\r\n var length = 0.0;\r\n if ( this.components && (this.components.length > 1)) {\r\n for(var i=1, len=this.components.length; i} The spatial reference system\r\n * for the geometry coordinates. If not provided, Geographic/WGS84 is\r\n * assumed.\r\n * \r\n * Returns:\r\n * {Float} The appoximate geodesic length of the geometry in meters.\r\n */\r\n getGeodesicLength: function(projection) {\r\n var geom = this; // so we can work with a clone if needed\r\n if(projection) {\r\n var gg = new OpenLayers.Projection(\"EPSG:4326\");\r\n if(!gg.equals(projection)) {\r\n geom = this.clone().transform(projection, gg);\r\n }\r\n }\r\n var length = 0.0;\r\n if(geom.components && (geom.components.length > 1)) {\r\n var p1, p2;\r\n for(var i=1, len=geom.components.length; i\r\n */\r\nOpenLayers.Geometry.LineString = OpenLayers.Class(OpenLayers.Geometry.Curve, {\r\n\r\n /**\r\n * Constructor: OpenLayers.Geometry.LineString\r\n * Create a new LineString geometry\r\n *\r\n * Parameters:\r\n * points - {Array()} An array of points used to\r\n * generate the linestring\r\n *\r\n */\r\n\r\n /**\r\n * APIMethod: removeComponent\r\n * Only allows removal of a point if there are three or more points in \r\n * the linestring. (otherwise the result would be just a single point)\r\n *\r\n * Parameters: \r\n * point - {} The point to be removed\r\n *\r\n * Returns: \r\n * {Boolean} The component was removed.\r\n */\r\n removeComponent: function(point) {\r\n var removed = this.components && (this.components.length > 2);\r\n if (removed) {\r\n OpenLayers.Geometry.Collection.prototype.removeComponent.apply(this, \r\n arguments);\r\n }\r\n return removed;\r\n },\r\n \r\n /**\r\n * APIMethod: intersects\r\n * Test for instersection between two geometries. This is a cheapo\r\n * implementation of the Bently-Ottmann algorigithm. It doesn't\r\n * really keep track of a sweep line data structure. It is closer\r\n * to the brute force method, except that segments are sorted and\r\n * potential intersections are only calculated when bounding boxes\r\n * intersect.\r\n *\r\n * Parameters:\r\n * geometry - {}\r\n *\r\n * Returns:\r\n * {Boolean} The input geometry intersects this geometry.\r\n */\r\n intersects: function(geometry) {\r\n var intersect = false;\r\n var type = geometry.CLASS_NAME;\r\n if(type == \"OpenLayers.Geometry.LineString\" ||\r\n type == \"OpenLayers.Geometry.LinearRing\" ||\r\n type == \"OpenLayers.Geometry.Point\") {\r\n var segs1 = this.getSortedSegments();\r\n var segs2;\r\n if(type == \"OpenLayers.Geometry.Point\") {\r\n segs2 = [{\r\n x1: geometry.x, y1: geometry.y,\r\n x2: geometry.x, y2: geometry.y\r\n }];\r\n } else {\r\n segs2 = geometry.getSortedSegments();\r\n }\r\n var seg1, seg1x1, seg1x2, seg1y1, seg1y2,\r\n seg2, seg2y1, seg2y2;\r\n // sweep right\r\n outer: for(var i=0, len=segs1.length; i seg1x2) {\r\n // seg1 still left of seg2\r\n break;\r\n }\r\n if(seg2.x2 < seg1x1) {\r\n // seg2 still left of seg1\r\n continue;\r\n }\r\n seg2y1 = seg2.y1;\r\n seg2y2 = seg2.y2;\r\n if(Math.min(seg2y1, seg2y2) > Math.max(seg1y1, seg1y2)) {\r\n // seg2 above seg1\r\n continue;\r\n }\r\n if(Math.max(seg2y1, seg2y2) < Math.min(seg1y1, seg1y2)) {\r\n // seg2 below seg1\r\n continue;\r\n }\r\n if(OpenLayers.Geometry.segmentsIntersect(seg1, seg2)) {\r\n intersect = true;\r\n break outer;\r\n }\r\n }\r\n }\r\n } else {\r\n intersect = geometry.intersects(this);\r\n }\r\n return intersect;\r\n },\r\n \r\n /**\r\n * Method: getSortedSegments\r\n *\r\n * Returns:\r\n * {Array} An array of segment objects. Segment objects have properties\r\n * x1, y1, x2, and y2. The start point is represented by x1 and y1.\r\n * The end point is represented by x2 and y2. Start and end are\r\n * ordered so that x1 < x2.\r\n */\r\n getSortedSegments: function() {\r\n var numSeg = this.components.length - 1;\r\n var segments = new Array(numSeg), point1, point2;\r\n for(var i=0; i 0) {\r\n // sort intersections along segment\r\n var xDir = seg.x1 < seg.x2 ? 1 : -1;\r\n var yDir = seg.y1 < seg.y2 ? 1 : -1;\r\n result = {\r\n lines: lines,\r\n points: intersections.sort(function(p1, p2) {\r\n return (xDir * p1.x - xDir * p2.x) || (yDir * p1.y - yDir * p2.y);\r\n })\r\n };\r\n }\r\n return result;\r\n },\r\n\r\n /**\r\n * Method: split\r\n * Use this geometry (the source) to attempt to split a target geometry.\r\n * \r\n * Parameters:\r\n * target - {} The target geometry.\r\n * options - {Object} Properties of this object will be used to determine\r\n * how the split is conducted.\r\n *\r\n * Valid options:\r\n * mutual - {Boolean} Split the source geometry in addition to the target\r\n * geometry. Default is false.\r\n * edge - {Boolean} Allow splitting when only edges intersect. Default is\r\n * true. If false, a vertex on the source must be within the tolerance\r\n * distance of the intersection to be considered a split.\r\n * tolerance - {Number} If a non-null value is provided, intersections\r\n * within the tolerance distance of an existing vertex on the source\r\n * will be assumed to occur at the vertex.\r\n * \r\n * Returns:\r\n * {Array} A list of geometries (of this same type as the target) that\r\n * result from splitting the target with the source geometry. The\r\n * source and target geometry will remain unmodified. If no split\r\n * results, null will be returned. If mutual is true and a split\r\n * results, return will be an array of two arrays - the first will be\r\n * all geometries that result from splitting the source geometry and\r\n * the second will be all geometries that result from splitting the\r\n * target geometry.\r\n */\r\n split: function(target, options) {\r\n var results = null;\r\n var mutual = options && options.mutual;\r\n var sourceSplit, targetSplit, sourceParts, targetParts;\r\n if(target instanceof OpenLayers.Geometry.LineString) {\r\n var verts = this.getVertices();\r\n var vert1, vert2, seg, splits, lines, point;\r\n var points = [];\r\n sourceParts = [];\r\n for(var i=0, stop=verts.length-2; i<=stop; ++i) {\r\n vert1 = verts[i];\r\n vert2 = verts[i+1];\r\n seg = {\r\n x1: vert1.x, y1: vert1.y,\r\n x2: vert2.x, y2: vert2.y\r\n };\r\n targetParts = targetParts || [target];\r\n if(mutual) {\r\n points.push(vert1.clone());\r\n }\r\n for(var j=0; j 0) {\r\n lines.unshift(j, 1);\r\n Array.prototype.splice.apply(targetParts, lines);\r\n j += lines.length - 2;\r\n }\r\n if(mutual) {\r\n for(var k=0, len=splits.points.length; k 0 && points.length > 0) {\r\n points.push(vert2.clone());\r\n sourceParts.push(new OpenLayers.Geometry.LineString(points));\r\n }\r\n } else {\r\n results = target.splitWith(this, options);\r\n }\r\n if(targetParts && targetParts.length > 1) {\r\n targetSplit = true;\r\n } else {\r\n targetParts = [];\r\n }\r\n if(sourceParts && sourceParts.length > 1) {\r\n sourceSplit = true;\r\n } else {\r\n sourceParts = [];\r\n }\r\n if(targetSplit || sourceSplit) {\r\n if(mutual) {\r\n results = [sourceParts, targetParts];\r\n } else {\r\n results = targetParts;\r\n }\r\n }\r\n return results;\r\n },\r\n\r\n /**\r\n * Method: splitWith\r\n * Split this geometry (the target) with the given geometry (the source).\r\n *\r\n * Parameters:\r\n * geometry - {} A geometry used to split this\r\n * geometry (the source).\r\n * options - {Object} Properties of this object will be used to determine\r\n * how the split is conducted.\r\n *\r\n * Valid options:\r\n * mutual - {Boolean} Split the source geometry in addition to the target\r\n * geometry. Default is false.\r\n * edge - {Boolean} Allow splitting when only edges intersect. Default is\r\n * true. If false, a vertex on the source must be within the tolerance\r\n * distance of the intersection to be considered a split.\r\n * tolerance - {Number} If a non-null value is provided, intersections\r\n * within the tolerance distance of an existing vertex on the source\r\n * will be assumed to occur at the vertex.\r\n * \r\n * Returns:\r\n * {Array} A list of geometries (of this same type as the target) that\r\n * result from splitting the target with the source geometry. The\r\n * source and target geometry will remain unmodified. If no split\r\n * results, null will be returned. If mutual is true and a split\r\n * results, return will be an array of two arrays - the first will be\r\n * all geometries that result from splitting the source geometry and\r\n * the second will be all geometries that result from splitting the\r\n * target geometry.\r\n */\r\n splitWith: function(geometry, options) {\r\n return geometry.split(this, options);\r\n\r\n },\r\n\r\n /**\r\n * APIMethod: getVertices\r\n * Return a list of all points in this geometry.\r\n *\r\n * Parameters:\r\n * nodes - {Boolean} For lines, only return vertices that are\r\n * endpoints. If false, for lines, only vertices that are not\r\n * endpoints will be returned. If not provided, all vertices will\r\n * be returned.\r\n *\r\n * Returns:\r\n * {Array} A list of all vertices in the geometry.\r\n */\r\n getVertices: function(nodes) {\r\n var vertices;\r\n if(nodes === true) {\r\n vertices = [\r\n this.components[0],\r\n this.components[this.components.length-1]\r\n ];\r\n } else if (nodes === false) {\r\n vertices = this.components.slice(1, this.components.length-1);\r\n } else {\r\n vertices = this.components.slice();\r\n }\r\n return vertices;\r\n },\r\n\r\n /**\r\n * APIMethod: distanceTo\r\n * Calculate the closest distance between two geometries (on the x-y plane).\r\n *\r\n * Parameters:\r\n * geometry - {} The target geometry.\r\n * options - {Object} Optional properties for configuring the distance\r\n * calculation.\r\n *\r\n * Valid options:\r\n * details - {Boolean} Return details from the distance calculation.\r\n * Default is false.\r\n * edge - {Boolean} Calculate the distance from this geometry to the\r\n * nearest edge of the target geometry. Default is true. If true,\r\n * calling distanceTo from a geometry that is wholly contained within\r\n * the target will result in a non-zero distance. If false, whenever\r\n * geometries intersect, calling distanceTo will return 0. If false,\r\n * details cannot be returned.\r\n *\r\n * Returns:\r\n * {Number | Object} The distance between this geometry and the target.\r\n * If details is true, the return will be an object with distance,\r\n * x0, y0, x1, and x2 properties. The x0 and y0 properties represent\r\n * the coordinates of the closest point on this geometry. The x1 and y1\r\n * properties represent the coordinates of the closest point on the\r\n * target geometry.\r\n */\r\n distanceTo: function(geometry, options) {\r\n var edge = !(options && options.edge === false);\r\n var details = edge && options && options.details;\r\n var result, best = {};\r\n var min = Number.POSITIVE_INFINITY;\r\n if(geometry instanceof OpenLayers.Geometry.Point) {\r\n var segs = this.getSortedSegments();\r\n var x = geometry.x;\r\n var y = geometry.y;\r\n var seg;\r\n for(var i=0, len=segs.length; i maxDistance) {\r\n maxDistance = distance;\r\n indexFarthest = index;\r\n }\r\n }\r\n \r\n if (maxDistance > tolerance && indexFarthest != firstPoint) {\r\n //Add the largest point that exceeds the tolerance\r\n pointIndexsToKeep.push(indexFarthest);\r\n douglasPeuckerReduction(points, firstPoint, indexFarthest, tolerance);\r\n douglasPeuckerReduction(points, indexFarthest, lastPoint, tolerance);\r\n }\r\n };\r\n \r\n /**\r\n * Private function calculating the perpendicular distance\r\n * TODO: check whether OpenLayers.Geometry.LineString::distanceTo() is faster or slower\r\n */\r\n var perpendicularDistance = function(point1, point2, point){\r\n //Area = |(1/2)(x1y2 + x2y3 + x3y1 - x2y1 - x3y2 - x1y3)| *Area of triangle\r\n //Base = v((x1-x2)²+(x1-x2)²) *Base of Triangle*\r\n //Area = .5*Base*H *Solve for height\r\n //Height = Area/.5/Base\r\n \r\n var area = Math.abs(0.5 * (point1.x * point2.y + point2.x * point.y + point.x * point1.y - point2.x * point1.y - point.x * point2.y - point1.x * point.y));\r\n var bottom = Math.sqrt(Math.pow(point1.x - point2.x, 2) + Math.pow(point1.y - point2.y, 2));\r\n var height = area / bottom * 2;\r\n \r\n return height;\r\n };\r\n \r\n var firstPoint = 0;\r\n var lastPoint = points.length - 1;\r\n var pointIndexsToKeep = [];\r\n \r\n //Add the first and last index to the keepers\r\n pointIndexsToKeep.push(firstPoint);\r\n pointIndexsToKeep.push(lastPoint);\r\n \r\n //The first and the last point cannot be the same\r\n while (points[firstPoint].equals(points[lastPoint])) {\r\n lastPoint--;\r\n //Addition: the first point not equal to first point in the LineString is kept as well\r\n pointIndexsToKeep.push(lastPoint);\r\n }\r\n \r\n douglasPeuckerReduction(points, firstPoint, lastPoint, tolerance);\r\n var returnPoints = [];\r\n pointIndexsToKeep.sort(compareNumbers);\r\n for (var index = 0; index < pointIndexsToKeep.length; index++) {\r\n returnPoints.push(points[pointIndexsToKeep[index]]);\r\n }\r\n return new OpenLayers.Geometry.LineString(returnPoints);\r\n \r\n }\r\n else {\r\n return this;\r\n }\r\n },\r\n\r\n CLASS_NAME: \"OpenLayers.Geometry.LineString\"\r\n});\r\n\r\n\r\n/**\r\n * Function: OpenLayers.Geometry.LineString.geodesic\r\n *\r\n * Parameters:\r\n * interpolate - {function(number): OpenLayers.Geometry.Point} Interpolate\r\n * function.\r\n * transform - {function(OpenLayers.Geometry.Point): OpenLayers.Geometry.Point}\r\n * Transform from longitude/latitude to projected coordinates.\r\n * squaredTolerance - {number} Squared tolerance.\r\n *\r\n * Returns:\r\n * {OpenLayers.Geometry.LineString}\r\n */\r\nOpenLayers.Geometry.LineString.geodesic =\r\n function(interpolate, transform, squaredTolerance) {\r\n // FIXME reduce garbage generation\r\n // FIXME optimize stack operations\r\n\r\n var components = [];\r\n\r\n var geoA = interpolate(0);\r\n var geoB = interpolate(1);\r\n\r\n var a = transform(geoA);\r\n var b = transform(geoB);\r\n\r\n var geoStack = [geoB, geoA];\r\n var stack = [b, a];\r\n var fractionStack = [1, 0];\r\n\r\n var fractions = {};\r\n\r\n var maxIterations = 1e5;\r\n var geoM, m, fracA, fracB, fracM, key;\r\n\r\n while (--maxIterations > 0 && fractionStack.length > 0) {\r\n // Pop the a coordinate off the stack\r\n fracA = fractionStack.pop();\r\n geoA = geoStack.pop();\r\n a = stack.pop();\r\n // Add the a coordinate if it has not been added yet\r\n key = fracA.toString();\r\n if (!(key in fractions)) {\r\n components.push(a);\r\n fractions[key] = true;\r\n }\r\n // Pop the b coordinate off the stack\r\n fracB = fractionStack.pop();\r\n geoB = geoStack.pop();\r\n b = stack.pop();\r\n // Find the m point between the a and b coordinates\r\n fracM = (fracA + fracB) / 2;\r\n geoM = interpolate(fracM);\r\n m = transform(geoM);\r\n if (OpenLayers.Geometry.distanceSquaredToSegment(m, {x1: a.x, y1: a.y,\r\n x2: b.x, y2: b.y}).distance < squaredTolerance) {\r\n // If the m point is sufficiently close to the straight line, then\r\n // we discard it. Just use the b coordinate and move on to the next\r\n // line segment.\r\n components.push(b);\r\n key = fracB.toString();\r\n fractions[key] = true;\r\n } else {\r\n // Otherwise, we need to subdivide the current line segment.\r\n // Split it into two and push the two line segments onto the stack.\r\n fractionStack.push(fracB, fracM, fracM, fracA);\r\n stack.push(b, m, m, a);\r\n geoStack.push(geoB, geoM, geoM, geoA);\r\n }\r\n }\r\n\r\n return new OpenLayers.Geometry.LineString(components);\r\n};\r\n\r\n\r\n/**\r\n * Function: OpenLayers.Geometry.LineString.geodesicMeridian\r\n * Generate a meridian (line at constant longitude).\r\n *\r\n * Parameters:\r\n * lon - {number} Longitude.\r\n * lat1 - {number} Latitude 1.\r\n * lat2 - {number} Latitude 2.\r\n * projection - {OpenLayers.Projection} Projection.\r\n * squaredTolerance - {number} Squared tolerance.\r\n *\r\n * Returns:\r\n * {OpenLayers.Geometry.LineString} Line geometry for the meridian at .\r\n */\r\nOpenLayers.Geometry.LineString.geodesicMeridian =\r\n function(lon, lat1, lat2, projection, squaredTolerance) {\r\n var epsg4326Projection = new OpenLayers.Projection('EPSG:4326');\r\n return OpenLayers.Geometry.LineString.geodesic(\r\n function(frac) {\r\n return new OpenLayers.Geometry.Point(\r\n lon, lat1 + ((lat2 - lat1) * frac));\r\n },\r\n function(point) {\r\n return point.transform(epsg4326Projection, projection);\r\n },\r\n squaredTolerance\r\n );\r\n};\r\n\r\n\r\n/**\r\n * Function: OpenLayers.Geometry.LineString.geodesicParallel\r\n * Generate a parallel (line at constant latitude).\r\n *\r\n * Parameters:\r\n * lat - {number} Latitude.\r\n * lon1 - {number} Longitude 1.\r\n * lon2 - {number} Longitude 2.\r\n * projection {OpenLayers.Projection} Projection.\r\n * squaredTolerance - {number} Squared tolerance.\r\n *\r\n * Returns:\r\n * {OpenLayers.Geometry.LineString} Line geometry for the parallel at .\r\n */\r\nOpenLayers.Geometry.LineString.geodesicParallel =\r\n function(lat, lon1, lon2, projection, squaredTolerance) {\r\n var epsg4326Projection = new OpenLayers.Projection('EPSG:4326');\r\n return OpenLayers.Geometry.LineString.geodesic(\r\n function(frac) {\r\n return new OpenLayers.Geometry.Point(\r\n lon1 + ((lon2 - lon1) * frac), lat);\r\n },\r\n function(point) {\r\n return point.transform(epsg4326Projection, projection);\r\n },\r\n squaredTolerance\r\n );\r\n};\r\n\r\n/* ======================================================================\r\n OpenLayers/Geometry/LinearRing.js\r\n ====================================================================== */\r\n\r\n/* Copyright (c) 2006-2015 by OpenLayers Contributors (see authors.txt for\r\n * full list of contributors). Published under the 2-clause BSD license.\r\n * See license.txt in the OpenLayers distribution or repository for the\r\n * full text of the license. */\r\n\r\n/**\r\n * @requires OpenLayers/Geometry/LineString.js\r\n */\r\n\r\n/**\r\n * Class: OpenLayers.Geometry.LinearRing\r\n * \r\n * A Linear Ring is a special LineString which is closed. It closes itself \r\n * automatically on every addPoint/removePoint by adding a copy of the first\r\n * point as the last point. \r\n * \r\n * Also, as it is the first in the line family to close itself, a getArea()\r\n * function is defined to calculate the enclosed area of the linearRing\r\n * \r\n * Inherits:\r\n * - \r\n */\r\nOpenLayers.Geometry.LinearRing = OpenLayers.Class(\r\n OpenLayers.Geometry.LineString, {\r\n\r\n /**\r\n * Property: componentTypes\r\n * {Array(String)} An array of class names representing the types of \r\n * components that the collection can include. A null \r\n * value means the component types are not restricted.\r\n */\r\n componentTypes: [\"OpenLayers.Geometry.Point\"],\r\n\r\n /**\r\n * Constructor: OpenLayers.Geometry.LinearRing\r\n * Linear rings are constructed with an array of points. This array\r\n * can represent a closed or open ring. If the ring is open (the last\r\n * point does not equal the first point), the constructor will close\r\n * the ring. If the ring is already closed (the last point does equal\r\n * the first point), it will be left closed.\r\n * \r\n * Parameters:\r\n * points - {Array()} points\r\n */\r\n\r\n /**\r\n * APIMethod: addComponent\r\n * Adds a point to geometry components. If the point is to be added to\r\n * the end of the components array and it is the same as the last point\r\n * already in that array, the duplicate point is not added. This has \r\n * the effect of closing the ring if it is not already closed, and \r\n * doing the right thing if it is already closed. This behavior can \r\n * be overridden by calling the method with a non-null index as the \r\n * second argument.\r\n *\r\n * Parameters:\r\n * point - {}\r\n * index - {Integer} Index into the array to insert the component\r\n * \r\n * Returns:\r\n * {Boolean} Was the Point successfully added?\r\n */\r\n addComponent: function(point, index) {\r\n var added = false;\r\n\r\n //remove last point\r\n var lastPoint = this.components.pop();\r\n\r\n // given an index, add the point\r\n // without an index only add non-duplicate points\r\n if(index != null || !point.equals(lastPoint)) {\r\n added = OpenLayers.Geometry.Collection.prototype.addComponent.apply(this, \r\n arguments);\r\n }\r\n\r\n //append copy of first point\r\n var firstPoint = this.components[0];\r\n OpenLayers.Geometry.Collection.prototype.addComponent.apply(this, \r\n [firstPoint]);\r\n \r\n return added;\r\n },\r\n \r\n /**\r\n * APIMethod: removeComponent\r\n * Removes a point from geometry components.\r\n *\r\n * Parameters:\r\n * point - {}\r\n *\r\n * Returns: \r\n * {Boolean} The component was removed.\r\n */\r\n removeComponent: function(point) {\r\n var removed = this.components && (this.components.length > 3);\r\n if (removed) {\r\n //remove last point\r\n this.components.pop();\r\n \r\n //remove our point\r\n OpenLayers.Geometry.Collection.prototype.removeComponent.apply(this, \r\n arguments);\r\n //append copy of first point\r\n var firstPoint = this.components[0];\r\n OpenLayers.Geometry.Collection.prototype.addComponent.apply(this, \r\n [firstPoint]);\r\n }\r\n return removed;\r\n },\r\n \r\n /**\r\n * APIMethod: move\r\n * Moves a geometry by the given displacement along positive x and y axes.\r\n * This modifies the position of the geometry and clears the cached\r\n * bounds.\r\n *\r\n * Parameters:\r\n * x - {Float} Distance to move geometry in positive x direction. \r\n * y - {Float} Distance to move geometry in positive y direction.\r\n */\r\n move: function(x, y) {\r\n for(var i = 0, len=this.components.length; i} Center point for the rotation\r\n */\r\n rotate: function(angle, origin) {\r\n for(var i=0, len=this.components.length; i} Point of origin for resizing\r\n * ratio - {Float} Optional x:y ratio for resizing. Default ratio is 1.\r\n * \r\n * Returns:\r\n * {} - The current geometry. \r\n */\r\n resize: function(scale, origin, ratio) {\r\n for(var i=0, len=this.components.length; i}\r\n * dest - {}\r\n * \r\n * Returns:\r\n * {} \r\n */\r\n transform: function(source, dest) {\r\n if (source && dest) {\r\n for (var i=0, len=this.components.length; i} The centroid of the collection\r\n */\r\n getCentroid: function() {\r\n if (this.components) {\r\n var len = this.components.length;\r\n if (len > 0 && len <= 2) {\r\n return this.components[0].clone();\r\n } else if (len > 2) {\r\n var sumX = 0.0;\r\n var sumY = 0.0;\r\n var x0 = this.components[0].x;\r\n var y0 = this.components[0].y;\r\n var area = -1 * this.getArea();\r\n if (area != 0) {\r\n for (var i = 0; i < len - 1; i++) {\r\n var b = this.components[i];\r\n var c = this.components[i+1];\r\n sumX += (b.x + c.x - 2 * x0) * ((b.x - x0) * (c.y - y0) - (c.x - x0) * (b.y - y0));\r\n sumY += (b.y + c.y - 2 * y0) * ((b.x - x0) * (c.y - y0) - (c.x - x0) * (b.y - y0));\r\n }\r\n var x = x0 + sumX / (6 * area);\r\n var y = y0 + sumY / (6 * area);\r\n } else {\r\n for (var i = 0; i < len - 1; i++) {\r\n sumX += this.components[i].x;\r\n sumY += this.components[i].y;\r\n }\r\n var x = sumX / (len - 1);\r\n var y = sumY / (len - 1);\r\n }\r\n return new OpenLayers.Geometry.Point(x, y);\r\n } else {\r\n return null;\r\n }\r\n }\r\n },\r\n\r\n /**\r\n * APIMethod: getArea\r\n * Note - The area is positive if the ring is oriented CW, otherwise\r\n * it will be negative.\r\n * \r\n * Returns:\r\n * {Float} The signed area for a ring.\r\n */\r\n getArea: function() {\r\n var area = 0.0;\r\n if ( this.components && (this.components.length > 2)) {\r\n var sum = 0.0;\r\n for (var i=0, len=this.components.length; i} The spatial reference system\r\n * for the geometry coordinates. If not provided, Geographic/WGS84 is\r\n * assumed.\r\n * \r\n * Reference:\r\n * Robert. G. Chamberlain and William H. Duquette, \"Some Algorithms for\r\n * Polygons on a Sphere\", JPL Publication 07-03, Jet Propulsion\r\n * Laboratory, Pasadena, CA, June 2007 http://trs-new.jpl.nasa.gov/dspace/handle/2014/40409\r\n *\r\n * Returns:\r\n * {float} The approximate signed geodesic area of the polygon in square\r\n * meters.\r\n */\r\n getGeodesicArea: function(projection) {\r\n var ring = this; // so we can work with a clone if needed\r\n if(projection) {\r\n var gg = new OpenLayers.Projection(\"EPSG:4326\");\r\n if(!gg.equals(projection)) {\r\n ring = this.clone().transform(projection, gg);\r\n }\r\n }\r\n var area = 0.0;\r\n var len = ring.components && ring.components.length;\r\n if(len > 2) {\r\n var p1, p2;\r\n for(var i=0; i}\r\n *\r\n * Returns:\r\n * {Boolean | Number} The point is inside the linear ring. Returns 1 if\r\n * the point is coincident with an edge. Returns boolean otherwise.\r\n */\r\n containsPoint: function(point) {\r\n var approx = OpenLayers.Number.limitSigDigs;\r\n var digs = 14;\r\n var px = approx(point.x, digs);\r\n var py = approx(point.y, digs);\r\n function getX(y, x1, y1, x2, y2) {\r\n return (y - y2) * ((x2 - x1) / (y2 - y1)) + x2;\r\n }\r\n var numSeg = this.components.length - 1;\r\n var start, end, x1, y1, x2, y2, cx, cy;\r\n var crosses = 0;\r\n for(var i=0; i= x1 && px <= x2) || // right or vert\r\n x1 >= x2 && (px <= x1 && px >= x2)) { // left or vert\r\n // point on edge\r\n crosses = -1;\r\n break;\r\n }\r\n }\r\n // ignore other horizontal edges\r\n continue;\r\n }\r\n cx = approx(getX(py, x1, y1, x2, y2), digs);\r\n if(cx == px) {\r\n // point on line\r\n if(y1 < y2 && (py >= y1 && py <= y2) || // upward\r\n y1 > y2 && (py <= y1 && py >= y2)) { // downward\r\n // point on edge\r\n crosses = -1;\r\n break;\r\n }\r\n }\r\n if(cx <= px) {\r\n // no crossing to the right\r\n continue;\r\n }\r\n if(x1 != x2 && (cx < Math.min(x1, x2) || cx > Math.max(x1, x2))) {\r\n // no crossing\r\n continue;\r\n }\r\n if(y1 < y2 && (py >= y1 && py < y2) || // upward\r\n y1 > y2 && (py < y1 && py >= y2)) { // downward\r\n ++crosses;\r\n }\r\n }\r\n var contained = (crosses == -1) ?\r\n // on edge\r\n 1 :\r\n // even (out) or odd (in)\r\n !!(crosses & 1);\r\n\r\n return contained;\r\n },\r\n\r\n /**\r\n * APIMethod: intersects\r\n * Determine if the input geometry intersects this one.\r\n *\r\n * Parameters:\r\n * geometry - {} Any type of geometry.\r\n *\r\n * Returns:\r\n * {Boolean} The input geometry intersects this one.\r\n */\r\n intersects: function(geometry) {\r\n var intersect = false;\r\n if(geometry.CLASS_NAME == \"OpenLayers.Geometry.Point\") {\r\n intersect = this.containsPoint(geometry);\r\n } else if(geometry.CLASS_NAME == \"OpenLayers.Geometry.LineString\") {\r\n intersect = geometry.intersects(this);\r\n } else if(geometry.CLASS_NAME == \"OpenLayers.Geometry.LinearRing\") {\r\n intersect = OpenLayers.Geometry.LineString.prototype.intersects.apply(\r\n this, [geometry]\r\n );\r\n } else {\r\n // check for component intersections\r\n for(var i=0, len=geometry.components.length; i \r\n * - \r\n */\r\nOpenLayers.Geometry.Polygon = OpenLayers.Class(\r\n OpenLayers.Geometry.Collection, {\r\n\r\n /**\r\n * Property: componentTypes\r\n * {Array(String)} An array of class names representing the types of\r\n * components that the collection can include. A null value means the\r\n * component types are not restricted.\r\n */\r\n componentTypes: [\"OpenLayers.Geometry.LinearRing\"],\r\n\r\n /**\r\n * Constructor: OpenLayers.Geometry.Polygon\r\n * Constructor for a Polygon geometry. \r\n * The first ring (this.component[0])is the outer bounds of the polygon and \r\n * all subsequent rings (this.component[1-n]) are internal holes.\r\n *\r\n *\r\n * Parameters:\r\n * components - {Array()} \r\n */\r\n\r\n /** \r\n * APIMethod: getArea\r\n * Calculated by subtracting the areas of the internal holes from the \r\n * area of the outer hole.\r\n * \r\n * Returns:\r\n * {float} The area of the geometry\r\n */\r\n getArea: function() {\r\n var area = 0.0;\r\n if ( this.components && (this.components.length > 0)) {\r\n area += Math.abs(this.components[0].getArea());\r\n for (var i=1, len=this.components.length; i